Jsp&Servlet

Servlet

Servlet 的生命周期

  • 当 servlet 首次被访问时 ,调用构造方法,只调用一次(只有一个servlet对象被创建)
  • 紧接着调用初始化 init 方法,也是只调用一次
  • 根据请求方式,调用 service,或 doGet 或 doPost (请求几次,就会被调用几次)
  • 当应用程序停止前,调用 destroy 方法,只调用一次

这些方法都是由 tomcat 容器来调用, 这种方式称之为控制反转

Servlet 默认是在第一次访问时被加载,也可以配置服务器启动时被加载 loadOnStartup = 数字
数字代表优先级,数字小的表示优先级高

还可以设置初始化参数(了解)

Servlet 2.5 以前的版本

webapp/WEB-INF/web.xml (部署描述符)
在这里也可以配置servlet中的所有功能,例如:

<servlet>
    <!-- servlet 名字 -->
    <servlet-name>old</servlet-name>
    <!-- servlet 对应的 java 类-->
    <servlet-class>web.OldServlet</servlet-class>
    <!-- 初始化参数 -->
    <init-param>
        <param-name>name</param-name>
        <param-value>李四</param-value>
    </init-param>
    <!-- 让 servlet 在启动时加载,优先级是 3 -->
    <load-on-startup>3</load-on-startup>
</servlet>

<servlet-mapping>
    <!-- servlet 名字, 与上面对应 -->
    <servlet-name>old</servlet-name>
    <!-- servlet 访问路径 -->
    <url-pattern>/old</url-pattern>
</servlet-mapping>

1. post 请求中的汉字会有乱码问题(重点)

原因:

String sex = URLEncoder.encode("男", "utf-8");
System.out.println(sex);
// iso-8859-1
String result = URLDecoder.decode("%E7%94%B7", "iso-8859-1");
System.out.println(result); // ç”·

解决方法,在调用 getParameter 方法之前:

request.setCharacterEncoding("utf-8")

2. request 重要方法(重点)

request.getParameter(“参数名”) => 返回参数值
request.getParameterValues(“参数名”) => 返回参数值的数组
request.getParameterNames(); 取得所有的参数列表 返回一个Enumeration对象
request.getReader() =>取得BufferedReader对象,可以得到<body>中的数据

Enumeration<string> e= req.getParamaterNames();
		while(e.hasMoreElements() ){
			String param = e.nextElement();
		  	...
		}

request.setCharacterEncoding(“解码的字符集”);

request.getMethod(); ==> 返回请求方式 get, post
request.getRequestURI(); ==> 返回当前的请求路径
request.getRemoteAddr(); ==> 获取访问者的ip地址

3. 一个请求分别几个部分(了解)

GET 两个部分
GET 路径/HTTP 1.1   ==> 请求行
请求头
    Host: 要访问那个虚拟主机 一个服务器下有多有 host, 每一个host 下,又有多个应用程序
    Accept: 可以处理的内容格式:例如 text/html
    Accept-Encoding : 能够支持的压缩格式
    Accept-Language : 支持的语言, 例如 zh-CN
POST 三个部分
    Content-Type: 请求体的格式 application/www-form-urlencoded (普通表单格式)
    Content-Length: 请求体内容的长度
请求体
    post的请求参数放入了请求体当中,例如:username=zhangsan&password=123
    如果有中文,会自动编码 

4. 响应分成3个部分(了解)

  1. 状态码

    • 200 表示响应正确返回
    • 404 表示请求的资源不存在
    • 500 表示服务器内部出现了异常
    • 304 表示该内容没有被修改,那么服务器只会返回状态码和头,不需要返回响应体(图片,html,css,js)
    • 400 请求参数格式有误.
    • 403 验证没通过,或权限不足
  2. 响应头

    • content-type: 响应的内容格式, 例如 text/html;charset=utf8
    • content-length: 响应体的长度(字节)
    • Date: 响应生成时间
  3. 响应体
    html内容,图片内容

5. 返回一个动态图片(了解)

  1. 创建图片对象, 构造参数分别代表 宽、高、图片格式
    BufferedImage image = new BufferedImage();
  2. 创建画布对象
    Graphics2D g = image.createGraphics();
  3. 填充画布
    g.setColor(Color.GREEN);
    g.fillRect(0,0,200,100);
  4. 写入文字
    g.drawString(s, 0, 32);
  5. 把图片内容输出到响应
    resp.setContentType(“image/png”);
    // 参数1 图片对象, 参数2 图片压缩格式 png|jpeg, 参数3: 输出字节流
    ImageIO.write(image, “png”, resp.getOutputStream());
 // 1. 创建图片对象, 构造参数分别代表 宽、高、图片格式
        BufferedImage image = new BufferedImage(200, 100, BufferedImage.TYPE_INT_RGB);

        // 2. 创建画布对象
        Graphics2D g = image.createGraphics();

        // 3. 填充画布
        g.setColor(Color.GREEN);
        g.fillRect(0,0,200,100);
        // 写入文字
        g.setColor(Color.BLACK);
        g.setFont(new Font("微软雅黑", Font.ITALIC, 32));
        String s = random(4);
        g.drawString(s, 0, 32);

        g.setColor(Color.RED);
        g.drawLine(0,0,200,100);

        // 4. 把图片内容输出到响应
        resp.setContentType("image/png");
        // 参数1 图片对象, 参数2 图片压缩格式 png|jpeg, 参数3: 输出字节流
        ImageIO.write(image, "png", resp.getOutputStream());

6.输出二进制字符

使用HTTPServletResponse的getOutputStream()方法取得ServletOutputStream实例。

@WevServlet("/download.do")
public class Download extends HttpServlet(HttpServletReuset req,
HttpServletResponse resp){
	//设置响应内容类型
	resp.setContentType("application/pdf");
	InputStream in = getServletContext().getResourceAsStream("/WEB-INF/jdbc.pdf");
	OutputStream out = resp.getOutputStream();
	writeBytes(in,out);
	private void WriteBytes(InputStream in, OutputStream out){
		byte[] buffer = new byte[1024];
		int length=-1;
		while((length=in.read(buffer))!=-1){
			out.write(buffer,0,length);
		}
		in.close();
		out.close();
	}
}

7.取得上传文件

request.getPart(“name”)用于取得HTML中file框中上传的文件会返回一个Part对象其中Con-Disposition:区段存放了文件的描述信息。

public class UploadServlet extends HttpServlet{
	protected void doPost(HttpServletRequest req,
						HttpServletResponse resp){
	Part part = request.getPart("name");
	String filename = getFilename(part);
	//存入文件
	part.write(filename);
	/*取得上传文件名*/
	private String getFilename(Prat part){
		String header = part.getHeader("Con-Disposition:");
		String filename=header.substring(header.indexOf("filename=\"") + 10,
		header.lastIndexOf("\"") );
		return filename;
	}
	}
}

8. 请求转发(重点)

servlet 中还是用来处理表单请求

跳转至jsp (请求转发)

jsp 用来生成html代码并返回

request.getRequestDispatcher("jsp路径").forward(request, response);

如何把servlet中的变量传递给jsp显示

作用域传参

request.setAttribute("变量名", 对象);

取(在jsp页面),通过 EL 表达式取

${ 变量名 }
${ 变量名.属性名 }    el 表达式中的属性名,对应着java对象中的 get,set方法名

jsp 底层原理

在第一次发送请求时,会把 jsp 文件转义为 java(servlet) 代码,并进一步编译为 class 文件

把页面上的静态内容(html代码),使用 out.write 方法进行打印,其中 out 对应着响应的字符输出流
至于 <% 代码 %> 中的代码会原封不动搬移到 jsp 转义生成的 java 代码中

本质仍是一个 servlet

旧的生成动态内容的方式

  1. <% 代码 %> 称为jsp脚本, 其中的变量是方法内的局部变量
  2. <%= 表达式%> 称为jsp表达式, 用来输出值,不用加;结束
    使用jsp表达式获取作用域内容 <%= request.getAttribute("name") %>
    使用el表达式获取作用域的内容 ${name}
  3. <%! 代码 %> jsp的声明, 其中的变量是类的成员变量
  4. 注释 <%-- 注释内容 --%> 会阻止java代码的运行,包括 jstl 标签和 EL 表达式 都可以使用这种办法注释
  5. <%@ 指令名 %>
    • page 用来指明页面的内容类型和编码方式 , isELIgnored=“true|false” 表示是否忽略 EL 表达式
    • taglib 用来引入一个标签库 prefix=“前缀” uri=“标签库的标识”
    • include 用来执行页面的包含操作
<%@ include file="文件路径" %>

新的方式

jstl 标签 + EL 表达式 (推荐)

jsp 中的 EL 表达式

expression language
主要作用是从作用域中取出变量并显示

request.setAttribute(“变量名”, 值);

页面上可以使用 ${ 变量名.属性 }

1. 做简单运算

<h3>算数运算 ${ 18 + 20 }</h3>
<h3>比较运算 ${ 18 > 20 }</h3>
<h3>逻辑运算 ${ 18 > 20 and 19 < 30 }</h3>
<h3>逻辑运算 ${ 18 > 20 or 19 < 30 }</h3>
<h3>逻辑运算 ${ not (18 > 20) }</h3>
<h3>三元运算 ${ (false)?"真":"假" }</h3>
<h3>空运算 ${ empty names}</h3>

2. 用来显示作用域中的变量 (重点)

  • list 显示 可以用 [下标]
  • 要显示大小 list.size()
  • map 显示 可以用 ${map.key}
  • map 显示 可以用 ${map[“key”]}
  • map 显示 可以用 ${map.get(“key”)}
  • 建议map使用字符串作为key,如果非要用整数作为key,必须用 Long, 只能用[]语法取,不能用.语法
  • 显示java bean, 底层实际调用的是get方法,嵌套的对象可以多次调用.语法

3. 11 个隐式对象

  • param 代表是请求参数的map集合,用在一个参数有一个值的情况, key对应参数名,value对应参数值
  • paramValues 代表是请求参数的map集合,用在一个参数有多个值的情况, key对应参数名,value对应参数值的数组

4. 标准标签库

简称jstl

  1. 引入标签库 jar包
<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
  1. 在页面上声明要使用的标签库
<%@ taglib prefix="标签前缀" uri="标签的唯一标识" %>

核心标签

  • forEach 进行遍历
<c:forEach items="要遍历的集合" var="临时变量名" begin="起始的下标" end="结束下标" varStatus="保存下标的对象">
</c:forEach>

其中 varStatus 中有两个属性 count(从1开始) , index(从0开始)

  • if 条件判断
<c:if test="条件">内容</c:if>
  • choose 条件判断
<c:choose>
    <c:when test="条件1">内容</c:when>
    <c:when test="条件2">内容</c:when>
    <c:when test="条件3">内容</c:when>
    <c:otherwise>内容</c:otherwise>
</c:choose>
  • format
<fmt:formatNumber value="${number}" pattern="¤##,###.##" />
<fmt:formatNumber value="${number}" pattern="00000.00000"/>
<fmt:formatDate value="${date}" pattern="yyyy年MM月dd日 HH:mm:ss"/>
   

cookie (了解)

记住用户名密码这些参数的操作,称之为维护状态(记住这些信息)

cookie 本意是小甜点, 在web开发中是用来维系状态的一种技术

服务器要向浏览器返回cookie

// 创建cookie
Cookie c = new Cookie(,);
response.addCookie(c);

浏览器再发送请求时,会把这些cookie值重新发送给服务器

Cookie[] cookies = request.getCookies();
// 遍历 cookies 数组

应用场景: 自动登录、 记录访问网页

cookie 的属性

maxAge 用来设置 cookie 的寿命,

  • 默认不设置(-1)表示浏览器关闭寿命就到期
  • 指定一个正整数(单位秒),指定cookie存活多久
  • 设置为 0,表示由服务器端删除该cookie

httpOnly 用来设置是否禁止 js 代码访问 cookie

有安全风险,因为信息是存储在浏览器端的

session (重点)

把这些状态信息存储在服务器端,安全性要比 cookie 高很多

1. 存储信息

// 拿到 session 对象
HttpSession session = request.getSession();
// 存储信息
session.setAttribute("名",);

2. 获取信息

// 拿到 session 对象
HttpSession session = request.getSession();
// 获取信息 
session.getAttribute("名"); // 返回上一次存储的值

3. 删除信息

session.removeAttribute("名"); // 返回被移除的值

session.invalidate(); // 让session失效(全部清空)

默认生命周期,
第一次调用 request.getSession() 创建 session对象
如果隔了 30 分钟没有向服务器发送请求,session 会自动失效

如果要改变失效时间,可以在 web.xml中:

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

跟浏览器的关系:一个浏览器对应服务器端的一个 session 对象
他们存储的信息互不干扰

对比 cookie 和 session

  • 安全性上, session的安全性高,cookie的信息存在浏览器端所以不安全
  • 存储的类型, session 存储的类型是 Object, cookie 只能存字符串(并且需要进行编码处理)
  • 存储大小, session 理论上没有限制(但不建议存储太多内容), cookie 的限制:每个cookie不能超过4k,每个网站cookie个数也有限制的
  • 失效时间, session 两次请求间隔30分钟, cookie 默认关闭浏览器失效,还可以通过 maxAge 调整的更长

请求重定向 (重点)

请求转发

request.getRequestDispatcher("跳转路径").forward(request, response);

请求重定向

response.sendRedirect("跳转路径");

二者的区别

  • 请求转发的地址不会改动,始终是刚开始的地址, 请求重定向在跳转后,地址栏会变为目标地址
  • 请求转发是一次请求,跳转操作在服务器内部发生;请求重定向是两次请求,跳转操作是在浏览器,服务器之间发生
  • 请求转发可以使用 request.setAttribute 进行值的传递;请求重定向需要使用 session.setAttribute 进行值的传递

request, session 作用域(scope)对象 (重点)

作用范围限于一次请求
request.setAttribute(key, value);
request.getAttribute(key) ${key}
request.removeAttribute(key);

作用范围同一个浏览器的多次请求之间(一次会话)
session.setAttribute(key, value);
session.getAttribute(key) ${key}
session.removeAttribute(key);

页面作用域,作用范围限于当前页面
page

应用程序作用域,作用于整个应用程序
application

page < request < sesssion < application

${ key } 会从小的作用域向大的作用域依次查找,直到找到为止

也可以利用前缀精确地找某个作用域:

  • pageScope page 作用域
  • requestScope 请求作用域
  • sessionScope 会话作用域
  • applicationScope 应用程序作用域

jsp 中的隐式对象 (了解)

9 个

  • pageContext 页面作用域
  • request 请求对象
  • session 会话对象
  • application 应用程序对象
  • response 响应对象
  • out 响应输出流
  • page 当前的jsp对象(this)
  • config 用来读取和jsp配置相关的信息
  • exception 必须在当前页面的 page 指令中添加 isErrorPage=“true”, 表示一个异常对象

会话跟踪的原理

就是利用 jsessionid 的 cookie 把浏览器和session对象关联起来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值