EL表达式

1.概述

  1. Expression Language 表达式语言

  2. 作用:替换和简化jsp页面中Java代码的编写

  3. 语法:${ EL表达式 }

  4. 注意:jsp默认支持EL表达式,可以设置不解析表达式

    方法一:设置jsp中page指令中的:isELIgonred=”true”,忽略当前jsp页面中的所有EL表达式

    方法二: \${EL表达式} 忽略当前这个EL表达式

2.EL运算符

  1. 算术运算符:+ - * /(div) %(mod)

  2. 比较运算符:> < >= <= == !=

  3. 逻辑运算符:&&(and) ||(or) !(not)

  4. 空运算符:empty 用于判断字符串、集合、数组对象是否为null并且长度是否为0

    ${empty str}

    ${not empty str}

3.EL获取值

  1. EL表达式只能从域对象中获取值

  2. **语法一:${域名称.键名}**,从指定域中获取指定键的值,如果获取不到则不会显示任何内容(空字符串)

    • pageScope——->pageContext域

    • requestScope——>request域

    • sessionScope——>session

    • applicationScope——>application(servletContext)

    • 举例:在pageContext中存储,pageContext.setAttribute(“msg”,”hxx”);

      ​ 获取值,**${pageScope.msg}**

  3. **语法二:${键名}**,表示依次从最小的域中查找是否又该键对应的值,直到找到为止。

  4. 获取对象的值,对象的属性来获取,${域名称.键名.属性名},本质上会调用对象的getter方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class User {
    private Date date;
    /*
    * 逻辑视图
    * */
    public String getBirStr(){
    if (date!=null){
    //格式化日期对象
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //返回字符串
    return sdf.format(date);
    }else return null;
    }
    }
    <%--通过对象的属性来获取--%>
    <%
    User user = new User();
    user.setDate(new Date());
    request.setAttribute("u",user);
    %>
    ${u.birStr}
  5. List集合:${域名称.键名[索引]},越界时不显示任何内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <%
    List list = new ArrayList();
    list.add("hxxx");
    list.add(user);
    request.setAttribute("l",list);
    %>
    ${requestScope.l}<br>
    ${l[0]}<br>
    <%--越界什么都不显示--%>
    ${l[10]}<br>
    ${l[1].date}<br>
  6. Map:**${域名称.键名[“key名称”]} 或 ${域名称.键名.key名称}**

    1
    2
    3
    ${requestScope.m}<br>
    ${m.name}<br>
    ${m["name"]}

4.隐式对象

  1. EL表达式中有11个隐式对象

  2. pageContext

    • 获取jsp其他八个内置对象
    1
    2
    <%--在jsp中动态获取虚拟目录--%>
    ${pageContext.request.contextPath}

MVC开发模式

1.演进

  1. 早期只有servlet,只能使用response输出标签数据
  2. 后来出现jsp,简化了servlet的开发,但是如果过度使用jsp,在sp中写大量的Java代码,又写html等,会容易难于分工和维护
  3. 再后来Java的web开发借鉴MVC开发模式,使得程序的设计更加合理性

2.MVC

  1. M:Model,模型。JavaBean
    • 完成具体的业务操作,如查询数据库,封装对象
  2. V:View,视图。jsp
    • 展示数据
  3. C:Controller,控制器。servlet
    • 获取用户的输入
    • 调用模型
    • 将数据交给视图进行展示

Session服务器端会话技术

1. 概念

  • 服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象HttpSession中。

  • 获取session对象

    1
    2
    //获取session
    HttpSession session = request.getSession();
  • 使用HttpSession对象方法

    1. Object getAttribute(String name)
    2. void setAttribute(String name,Object value)
    3. void removeAttribute(String name)

2.原理

  • session的实现是依赖于cookie的。

    客户端浏览器访问服务器SessionDemo1资源时,该资源doget或者doPost方法中如果是第一次使用request.getSeesion()获取session对象,会在内存中创建一个session对象,并赋予一个ID值,服务器端的响应消息中携带set-cookie:JSESSION=ID值,浏览器保存该信息为cookie中。

    当客户端再次访问服务器资源时,再请求消息中包含cookie:JSESSION=ID值信息,服务器端再次使用request.getSeesion()获取session信息会在内存中查找是否有对应ID值的session对象。

3.session细节

  1. 当客户端关闭后,服务器端不关闭,两次获取session是否为同一个?

    • 默认情况下 不是
    • 如果需要获取同一个对象,则可以创建cookie,键为JSESSION,设置最大存活时间,让cookie持久化保存
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取session
    HttpSession session = request.getSession();
    System.out.println(session);
    //获取数据
    Object msg = session.getAttribute("msg");
    //手动将cookie JSESSIONID修改为当前session ID
    Cookie cookie = new Cookie("JSESSIONID", session.getId());
    cookie.setMaxAge(60);
    response.addCookie(cookie);
    System.out.println(msg);
    }
  1. 客户端不关闭,服务器关闭后,两次获取的session时同一个吗?

    • 不是同一个,但是要确保数据不丢失

      session的钝化:在服务器正常关闭之前,将session对象序列化到硬盘上

      session的活化:在服务器启动后,将session文件转化为内存中的session对象即可,原session中数据不会丢失,但是session对象ID不一样。

    • tomcat服务器会自动进行钝化和活化,SESSION.ser文件存放在服务器安装目录下的work目录中,但是IDEA钝化时会将SESSION.ser文件存放在web项目CATALINA_BASE目录下的\work\Catalina\localhost\项目名称文件夹中,但是重新启动服务器时会先删除work目录,然后重新建立一个work目录,所以不会活化。

  2. session的失效时间

    • 服务器关闭
    • session对象调用invaliddate()
    • session默认失效时间 30分钟,也可以在tomcat安装目录下的conf文件夹中的web.xml进行设置
    1
    2
    3
    <session-config>
    <session-timeout>30</session-timeout>
    </session-config>

4.session和cookie的区别

  • session运行在服务器端,cookie运行在客户端

  • cookie有大小和个数限制,session没有大小限制,而是和服务器的内存大小有关

  • cookie有安全隐患,通过拦截或本地文件找到cookie后来可以进行攻击

  • session保存在服务器一段时间后才会消失,session过多会增加服务器的压力

JSP简单学习

1.JSP原理

  • Java server Pages:Java服务器端页面。一个特殊的页面,既可以定义html标签,又可以定义Java代码

  • 原理:JSP本质上是一个Servlet,例如index.jsp,服务器启动后,浏览器访问index.jsp,在CATALINA_BASE目录下生成work目录,其中可以找到对应的index_jsp.class和index_jsp.java文件。

    其中,对应的类为index_jsp,继承了org.apache.jasper.runtime.HttpJspBase,在tomcat源码中HttpJspBase继承了HttpServlet。

    index_jsp.java文件中该类的_jspService方法中将index.jsp文件中的html标签输出到浏览器。

2.JSP脚本

  • jsp定义Java代码的地方

  • 定义方式

    1. <% 代码 %>:定义的Java代码,在_jspService方法中。 _jspService可以定义什么,该脚本就可以定义什么
    2. <%! 代码 %>:定义的Java代码,在jsp转换后的Java类中的成员位置,比如变量,静态代码块
    3. <%= 代码 %>:定义的Java代码,会输出到页面上
1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
hello
<%
System.out.println("hello jsp");
int i = 9;
%>
<%! private static int j;
static {
j=10;
}
%>
<%= i %>
</body>

3.JSP指令

  • 指令作用:用于配置JSP页面,导入资源文件

  • 格式:

    <%@ 指令名 属性名1=属性值1 属性名2=属性值2 %>

  • 指令分类

    1. page:配饰JSP页面

      • content-type:等于response.setContentType()。

        设置响应体的mime类型以及字符集

        设置当前jsp页面文件的编码(高级IDE可使用,如果是低级工具,则需要设置pageEncoding属性)

      • import:导包

      • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面。比如在index.jsp中发生异常,那么指定errorPage=”500.jsp”,在500.jsp文件中输出服务器正忙信息。

      • isErrorPage:标识当前是否为错误页面。

        true:是错误页面,可以使用内置对象exception,获取异常信息并输出到日志文件中

        false:不是错误页面,默认值。

    2. include:导入页面的资源文件

      <%@include file=”top.jsp”%>

    3. taglib:导入资源

4.JSP内置对象

  • 在JSP页面中不需要获取和创建,可以直接使用的对象。

例如:在_jspService方法的参数中有request和response,那么在jsp中就可以直接使用,在 _jspService方法中定义了out对象,那么在jsp中也可以使用。

1
2
3
4
<%
String contextPath = request.getContextPath();
out.print(contextPath);
%>
  • jsp有九个内置对象:request、response、out、pageContext、session、application、page、config、exception

    1. out:字符输出流对象,将数据输出到页面上。

      • out.write()和response.getWriter()的区别

        在tomcat服务器真正给客户端做出相应之前,会先找response缓冲区数据,在找out缓冲区数据。response.getWriter()数据输出永远在out.write()之前

    2. 作用

会话技术Cookie

1.简介

  • 会话:一次会话中包含多次请求和响应

    • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,知道有一方断开为止。
  • 功能:在一次会话的范围内的多次请求间,共享数据

  • 方式

    客户端会话技术:Cookie,将数据保存到客户端

    服务器端会话技术:Session

  • 快速入门:

    1. 创建Cookie对象,绑定数据

      new Cookie(String name,String value)

    2. 发送Cookie对象

      response.addCookie(Cookie cookie)

    3. 获取Cookie和数据

      Cookies[] request.getCookies()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    @WebServlet("/CookieDemo1")
    public class CookieDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //响应头 set-cookie
    Cookie cookie = new Cookie("msg","hello");
    response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
    }
    }

    @WebServlet("/CookieDemo2")
    public class CookieDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取请求头cookie
    Cookie[] cookies = request.getCookies();
    //遍历取值
    for (Cookie cookie : cookies) {
    if (cookie!=null){
    String name = cookie.getName();
    String value = cookie.getValue();
    System.out.println(name+"--->"+value);
    }
    }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
    }
    }

2.Cookie相关问题

  1. 一次可以发送多个cookie:可以创建多个cookie对象,使用response多次调用addCookie方法发送cookie即可

  2. cookie在浏览器中的保存时间

    • 默认情况下,当浏览器关闭后,Cookie数据被销毁

    • 持久化存储:setMaxAge(int seconds)

      参数值为正数:将cookie数据写到硬盘文件中。持久化存储,也代表cookie的存活时间

      参数值为负数:默认值

      参数值为0:删除cookie信息

  3. cookie存放中文

    • 在tomcat 8 之前,cookie不能直接存储中文

      需要将中文数据转码,一般采用URL编码

    • tomcat 8 之后,cookie支持中文。对特殊字符还是不支持,建议使用URL编码存储,URL解码

  4. cookie获取范围

    假设在一个tomcat服务器中,部署了多个web项目,那么这些web项目中的cookie能不能共享

    • 默认情况下cookie不能共享
    • setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录。如果要共享给部署在本服务器的其他项目,则可以将path设置为”/“;

    不同的tomcat服务器间cookie共享问题

    • setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享。

      比如setDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中cookie可以共享

3.cookie的特点和作用

  • cookie存储数据在客户端浏览器
  • 浏览器对于单个cookie的大小有限制以及对同一个域名下的总cookie数量也有限制
  • 作用
    1. cookie一般用于存储少量的不太敏感的数据
    2. 在不登陆的情况下,完成服务器对客户端的身份识别

下载文件时文件名乱码问题

1.问题分析

  • 实现浏览器客户端下载文件功能时,中文文件名出现乱码无法正常显示的情况。

2.原因分析

  • 首先HTTP协议中要求传输的header内容必须是ISO8859-1编码,当我们在代码中设置request和response编码格式为UTF-8后,就需要将接收到的中文参数值转换成ISO8859-1编码格式。

  • 下面html代码中链接标签中设置url的filename参数,对于filename=头像.jpg ,就需要转换编码格式。

    1
    2
    <a href="/test/ServletDownload?filename=avatar.jpg">下载图片</a>
    <a href="/test/ServletDownload?filename=头像.jpg">下载图片</a>

3.解决

  • filename = new String(filename.getBytes(“UTF-8”), “ISO8859-1”)

    因为ISO8859-1没有中文字符集,所以先获取到filename的UTF-8编码格式后,再将其转换成ISO8859-1格式。这些字符传递到浏览器后,浏览器会通过相反的方式String filename= new String(filename.getBytes(“ISO8859-1”),”UTF-8”)来得到正确的中文汉字,这样就既保证了遵守协议规定、也支持中文。

  • 如果直接ilename.getBytes(“ISO8859-1”),是不能正确转换的,因为ISO8859-1无法直接编码中文,所以更加无法还原。

4.文件下载实现代码

download.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>下载文件</title>
</head>
<body>
<!--指向servlet,传递资源名称filename-->
<a href="/test/ServletDownload?filename=avatar.jpg">下载图片</a>
<a href="/test/ServletDownload?filename=头像.jpg">下载图片</a>
<a href="/test/ServletDownload?filename=c.txt">下载txt</a>
</body>
</html>

ServletDownload.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@WebServlet("/ServletDownload")
public class ServletDownload extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 页面显示超链接
* 点击超链接后弹出下载提示框
* 完成图片文件下载
* */
request.setCharacterEncoding("UTF-8");
//1.获取文件名称,找到文件服务器路径
String filename = request.getParameter("filename");
ServletContext context = this.getServletContext();
String realPath = context.getRealPath("/img/" + filename);

//2.使用字节输入流加载文件进内存
FileInputStream fs = new FileInputStream(realPath);
//3.指定response的header content-disposition:attachment;filenamexxx
String mimeType = context.getMimeType(filename);//获取文件类型
response.setContentType(mimeType);

//tomcat默认编码 ISO8859-1,将获取到的UTF-8格式转换成ISO8859-1格式,然后在浏览器端或自动还原
if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
filename = new String(filename.getBytes("UTF-8"), "ISO8859-1"); // firefox浏览器
} else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
filename = URLEncoder.encode(filename, "UTF-8");// IE浏览器
}else if (request.getHeader("User-Agent").toUpperCase().indexOf("CHROME") > 0) {
filename = new String(filename.getBytes("UTF-8"), "ISO8859-1");// 谷歌
}

response.setHeader("content-disposition","attachment;filename="+filename);
//4.将输入流的数据写出到response输出流
ServletOutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while((len = fs.read(bytes)) != -1){
outputStream.write(bytes,0,len);
}
fs.close();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

ServletContext对象

1.ServletContext概述

  • 代表整个web应用,可以和程序的容器(服务器)来通信

  • 获取:

    1. 通过request对象获取,request.ServletContext();

    2. 通过HttpServlet获取:直接调用this.ServletContext();

  • 功能

    1. 获取MIME类型
    2. 域对象:共享数据
    3. 获取文件的真实(服务器)路径

2.获取MIME类型

  • MIME类型:在互联网通信过程中定义的一种文件数据类型

    • 格式:大类型/小类型 text/html image/jpg

    • 在服务器安装目录下/conf/web.xml中有对应关系

  • 获取:ServletContext对象调用**getMimeType(String file)**方法

3.域对象

  1. 方法

    • setAttribute(String name,Object value)

    • getAttribute(String name)

    • removeAttribute(String name)

  2. ServletContext对象范围:共享所有用户请求的数据

4.获取文件服务器

  1. 方法:getRealPath(String path)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@WebServlet("/ServletContextDemo3")
public class ServletContextDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象
ServletContext context = this.getServletContext();
//获取文件的服务器真实路径
//1.获取web目录下的a.txt
String bPath = context.getRealPath("/a.txt");
System.out.println(bPath);
//2.获取WEB-INF目录下的c.txt
String cPath = context.getRealPath("/WEB-INF/c.txt");
System.out.println(cPath);
//3.获取src目录下的a.txt
String aPath = context.getRealPath("/WEB-INF/classes/a.txt");
System.out.println(aPath);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

HTTP-response

1. HTTP协议补充

  1. 请求消息:客户端发送给服务器端的数据

    • 数据格式:请求行、请求头、请求空行、请求体
  2. 响应消息:服务器端发送给客户端的数据

    • 响应行

      1. 组成:协议/版本 响应状态码 状态码描述 HTTP/1.1 200 OK
      2. 响应状态码:服务器告诉客户端本次请求和响应的一个状态
        • 1XX:服务器接收客户端消息,但没有接收完成,等待一段时间发送1XX状态码。
        • 2XX:成功。代表200
        • 3XX:重定向。代表302(重定向)、304(访问缓存)
        • 4XX:客户端错误。404(请求路径没有对应的资源) 405(请求方式没有对应的doXxx方法)
        • 5XX:服务器端错误。500服务器端异常
    • 响应头

      1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式。text/html;charset:utf-8

      2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据

        • in-line:默认值,在当前页面内打开
        • attachment;filename=xxx:以附件形式打开响应体。文件下载
    • 响应空行

    • 响应体:传输的数据

2. response:设置响应消息

  1. 设置响应行

    • 设置状态码:setStatus(int sc)
  2. 设置响应头

    • setHeader(String name,String value)
  3. 设置响应体

    • 获取输出流
      1. 字符输出流:PrintWriter getWriter()
      2. 字节输出流:ServletOutputStream getOutputStream()
    • 使用输出流,将数据输出到客户端浏览器中

3.重定向

  • 当前服务器资源告诉浏览器重定向,状态码302

  • 告诉浏览器重定向资源的路径,响应头location:B资源的路径

  • 代码实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //获取虚拟路径
    String contextPath = request.getContextPath();
    //方法1
    //访问/responseDemo1,会自动跳转到/responseDemo2
    response.setStatus(302);
    //设置响应头
    response.setHeader("location",contextPath+"/responseDemo2");

    //方法2
    response.sendRedirect(contextPath+"/responseDemo2");
  • 特点

    重定向redirect的特点

    1. 地址栏发生变化
    2. 重定向可以访问其他站点(服务器)的资源
    3. 重定向是两次请求,不能用request对象来共享数据

    转发forward的特点

    1. 地址栏不发生变化
    2. 转发只能访问当前服务器下的资源
    3. 转发是一次请求,能用request对象来共享数据
  • 路径写法

    1. 路径分类

      相对路径:通过相对路径不可以确定唯一资源。以 . 开头,如./index.html。

      ​ 找到当前资源和目标资源之间的相对位置对应关系

      绝对路径:可以确定唯一资源。以/开头,如/test/demo

      ​ 给客户端浏览器使用:需要加虚拟目录。a或form标签 重定向。。。

      ​ 给服务器端使用:不需要加虚拟目录。转发

4.服务器输出字符数据到浏览器

  1. 获取字符输出流

  2. 输出数据

  3. 解决中文乱码问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("demo2......");
    //获取流对象之前,设置流的默认编码,默认是ISO-8859-1
    response.setCharacterEncoding("gbk");
    //告诉浏览器,服务器发送的消息体数据的编码。建议浏览器使用该编码
    //response.setHeader("content-type","text/html;charset=gbk");
    response.setContentType("text/html;charset=gbk");
    PrintWriter writer = response.getWriter();
    writer.write("<h1>hello response</h1>");
    writer.write("hello response");
    writer.write("你好 response");
    }

5.获取字节输出流

1
2
3
4
5
6
7
8
9
10
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo2......");
//获取流对象之前,设置流的默认编码,默认是ISO-8859-1
response.setCharacterEncoding("utf-8");
//告诉浏览器,服务器发送的消息体数据的编码。建议浏览器使用该编码
response.setContentType("text/html;charset=utf-8");
//获取字节输出流
ServletOutputStream os = response.getOutputStream();java
os.write("你好".getBytes("UTF-8"));///默认GBK,要和浏览器一致
}

6.验证码

  • 本质是一张图片
  • Checkcode代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@WebServlet("/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 50;
int height = 25;
//1.创建一个对象,在内存中图片(验证码图片对象)
BufferedImage Image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//2.美化图片
//获取画笔
Graphics graphics = Image.getGraphics();
//设置画笔颜色
graphics.setColor(Color.orange);
//填充颜色
graphics.fillRect(0,0,width,height);
graphics.setColor(Color.BLACK);
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
String code = "";
//生成随机角标
Random random = new Random();
for (int i = 1; i <= 4; i++) {
int index = random.nextInt(str.length());
//获取随机字符
char ch = str.charAt(index);
//写验证码
graphics.drawString(ch+"",width/5*i,height/2);
code += ch;
}
//画干扰线
graphics.setColor(Color.CYAN);
for (int i = 0; i < 10; i++) {
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
graphics.drawLine(x1,y1,x2,y2);
}
System.out.println(code);
//3.将图片输出到页面展示
ImageIO.write(Image,"jpg",response.getOutputStream());

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

regist.html

1
2
3
4
<form action="/test/requestdemo4"method="post">
<input type="text"name="checkcode"placeholder="请输入验证码">
<img id="check" src="/test/CheckCodeServlet" alt=""><br>
</form>

BeanUtils工具类

BeanUtils工具类

  • 封装JavaBean(标准的Java类)

  • 注意:

    1. 类必须被public修饰
    2. 必须提供空参的构造器
    3. 成员变量必须使用private修饰
    4. 提供公共的setter和getter方法
  • 类中的属性:setter和getter方法截取后的产物

    例如:getUsername() —->Username—–>username

    代码理解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    //UserTest类
    public class UserTest {
    public String getHehe() {
    return gender;
    }
    public void setHehe(String gender) {
    this.gender = gender;
    }
    @Override
    public String toString() {
    return "UserTest{" +
    "gender='" + gender + '\'' +
    '}';
    }
    private String gender;
    }
    //测试
    public class BeanUtilsTest {
    @Test
    public void test(){
    UserTest user = new UserTest();
    try {
    BeanUtils.setProperty(user,"hehe","hxx");
    System.out.println(user);
    String hehe = BeanUtils.getProperty(user, "hehe");
    System.out.println(hehe);
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    }
    }
    }
    public class BeanUtilsTest {
    @Test
    public void test(){
    UserTest user = new UserTest();
    try {
    //这里传的是根据setHehe和getHehe方法得到的hehe,进而给gender赋值
    BeanUtils.setProperty(user,"hehe","hxx");
    System.out.println(user);
    String hehe = BeanUtils.getProperty(user, "hehe");
    System.out.println(hehe);
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    }
    }
    }
  • 方法

    1. setProperty(属性名,属性值)
    2. getProperty(属性名,属性值)
    3. populate(Object obj,Map map):将map集合的键值对信息,封装到对应的JavaBean对象

spring中EmptyResultDataAccessException

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

使用template.queryForObject时发生异常

1
2
3
4
5
6
7
8
9
10
11
@Nullable
public static <T> T nullableSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
if (CollectionUtils.isEmpty(results)) {
throw new EmptyResultDataAccessException(1);
} else if (results.size() > 1) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
} else {
return results.iterator().next();
}
}

上面是nullableSingleResult方法中的源码,当results为空时,抛出EmptyResultDataAccessException

当返回值大小大于1时,抛出IncorrectResultSizeDataAccessException异常

所以在使用template.queryForObject时要进行异常处理

1
2
3
4
5
6
7
8
9
10
11
public static User login(User loginuser) {
//查询数据库
String sql = "select * from user where username = ? and password = ?";
User resUser = null;
try {
resUser = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), loginuser.getUsername(), loginuser.getPassword());
return resUser;
}catch (EmptyResultDataAccessException e) {
return null;
}
}