Java Web基础(Servlet、Cookie、Session、Jsp回顾整理)

一、servlet

servlet是JavaWeb三大组件之一,属于动态资源

servlet有两种创建顺序,第一是在服务器启动时创建,第二是用户访问时创建。服务器启动时创建需要在web.xml中配置0来实现,其中,0就是创建的次序,数字越小,越先创建。

实现 javax.servlet.Servlet 接口

生命周期方法:

  • void init(ServletConfig servletconfig) servlet被创建之后立即调用,只执行1次
  • void service(ServletRequest requset,ServletResponse servletresponse) 执行多次
  • void destory() servlet被销毁之前调用,只执行1次

特性:

  • 单例,一个类只有一个对象。可以存在多个servlet
  • 线程是不安全的,所以它的效率非常高

servlet由我们来写,但对象由服务器来创建,方法也由服务器来调用。

实现 javax.servlet.GenericServlet 类

实现 javax.servlet.HttpServlet 类

  • void service(ServletRequest req, ServletResponse res)
  • protected void service(HttpServletRequest req, HttpServletResponse resp)
  • protected void doPut(HttpServletRequest req, HttpServletResponse resp)
  • protected void doPost(HttpServletRequest req, HttpServletResponse resp)

HttpServlet类结构介绍:在实例化HttpServlet后,先调用service(ServletRequest, ServletResponse)方法,在这个方法中将ServletRequest和ServletResponse强转为HttpServletRequest和HttpServletResponse,最后根据HttpServletRequest中的参数决定调用doPost方法还是doGet方法

注意:如果没有覆写doPost或doGet方法,当这两个方法被调用时,浏览器会出现405错误,表示不支持该种请求方式。

ServletContext

一个项目中只有一个ServletContext(也叫做application),所以可以在多个servlet中利用这个对象来传递数据。

服务器为每一个应用程序创建ServletContext对象,ServletContext对象在服务器启动时创建,在服务器关闭时销毁。

获取ServletContext

  • ServletConfig#getServletContext()
  • GenericServlet#getServletContext()
  • HttpSession#getServletContext()
  • ServletContextEvent#getServletContext()

统计网页访问量小案例

从ServletContext中利用getAttribute方法获取访问量count值,如果访问量值为null,说明本次访问是第一次访问,利用setAttribute方法将访问量保存下来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Bservlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
Integer count = (Integer)servletContext.getAttribute("count");
if(count == null) {
servletContext.setAttribute("count",1);
}
else {
servletContext.setAttribute("count",count + 1);
}
PrintWriter pw = resp.getWriter();
pw.println("<h1>" + count + "</h1>");
}
}

PrintWriter是向网页输出的输出流,从response中获取对象。

获取类路径资源

如果在文件路径前写有‘/’,那么此时对准的文件路径起始点就是classes目录下,如果不写,那么对准的文件路径起始点就是 .class文件目录下。

两种方式:

  • ClassLoader
  • Class

ClassLoader

如果资源文件存在于src目录下,那么直接使用getResourceAsStream(“a.txt”),就可以获取文件资源;
如果资源文件存在于其它包目录下,假如存在于包web/day1_3下,那么将文件路径写全即可getResourceAsStream(“web/day1_3/a.txt”)。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class BServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ClassLoader classLoader = this.getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("web/day1_3/a.txt");
byte[] data = new byte[1024];
int len = 0;
while((len = input.read(data)) != -1) {
String line = new String(data,0,len);
System.out.println(line);
}
input.close();
}
}

Class

Class是相对于classes文件来说的。.java文件会被编译成.class文件存放于classes目录下。

如果资源文件与调用该文件的.class文件处于同一路径,那么直接使用getResourceAsStream(“a.txt”)即可;

如果处于不同路径,例如存放于src目录下,那么使用getResourceAsStream(“/a.txt”);

如果处于其它包下,例如存放于/web/day1_2下,而.class文件位于/web/day1_3下,那么使用getResourceAsStream(“/web/day1_2/a.txt”)即可。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class BServlet extends HttpServlet {

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

Class cl = this.getClass();
InputStream input = cl.getResourceAsStream("/web/day1_2/a.txt");
byte[] data = new byte[1024];
int len = 0;
while((len = input.read(data)) != -1) {
String line = new String(data,0,len);
System.out.println(line);
}
input.close();
}
}

二、cookie

cookie是以键值对的形式由服务器发送给浏览器保存在客户端上的。属于Http。

示例代码:

添加cookie

1
2
Cookie cookie1 = new Cookie("aaa","AAA");
response.addCookie(cookie1);

获取cookie的key

1
cookie.getName();

获取cookie的value

1
cookie.getValue()

设置cookie的生命周期

cookie#setMaxAge(int MaxAge);

  • MaxAge < 0,浏览器一旦关闭,该cookie即死亡
  • MaxAge = 0,该cookie立即被销毁
  • MaxAge > 0,cookie存活时间,以秒为单位

cookie的path:

如果访问路径包含cookie的保存路径,则会将该cookie带回给服务器

三、HttpSession

HttpSession是由JavaWeb提供的,Servlet三大域对象之一。


三大域对象:

  • request,一次请求对应一个request,但一个request可以在多个servlet中传递
  • session,一个用户对应一个session,同一个用户的请求都在同一个session内
  • application(ServletContex),一个应用程序对应一个application,应用程序不死,application不死

作用域范围

session的会话范围从用户打开浏览器访问服务器开始到关闭浏览器结束。
生命周期:session默认存活30分钟。

理解:一个Session就是一个会话。一个用户可以对一个服务器发出多个request,一个session包含多个request。

很少出现并发请求,session保存在服务器端。

转发:地址栏不发生改变,写的路径不需要带项目名
重定向:地址栏发生改变,写的路径需要带项目名。重定向后就是两个不同的请求

原理

当用户访问服务器时,服务器会创建一个session,并分配一个sessionId,这个sessionId跟创建的session对应。session会被保存在服务器端,而sessionId会被保存在cookie中。

创建了新的session,浏览器会得到一个包含sessionId的cookie,这个cookie的生命为-1,即只保存在内存中,当浏览器关闭时,cookie即被销毁。

之后请求session时,因为可以通过cookie中的sessionIs找到session,所以与上次请求的session是同一session对象。

服务器并不会一开始就创建session,而是第一次获取session时才会创建。

session最大不活跃时间

session有一个最大不活跃时间,当用户不对页面做任何操作时,session或被服务器销毁,下次就需要重新创建session,这样做可以保证用户信息安全。

四、JSP

三种jsp脚本

1、<% — %>,方法体内能写什么就能写什么

2、<%= — %>,out.write()能写什么就写什么

3、<%! — %>,类里面能写什么就能写什么,一般不用,用了会被敲死

jsp指令

一个jsp页面中,可以有0个或N个page指令。

三大指令:

  • page
  • include
  • taglib

page

1
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>

contentType和pageEncoding是等价的,一个什么值另一个也是同样的值,所以一般只用设置一个。如果两个都没有设置,那么默认是iso。

import:导入Java包,可以使用多次

errorPage:当当前页面抛出异常,则转发到指定页面,设置状态码为200

isErrorPage:设置某个页面为处理错误页面,当属性为true时,会设置状态码为500。并且只有这个页面能使用九大内置对象中的Exception。

include
静态包含,将多个jsp文件合并成一个文件然后被编译成.class文件,在运行之前就合并。

九大内置对象

  • out(response.getWriter()),jsp的输出流,用来响应客户端
  • page,当前jsp对象,它的引用类型是Object,即真身中有以下代码:Object page = this;
  • exception(Throwable)
  • request(HttpServletRequest)
  • response(HttpServletResponse)
  • config(ServletConfig),对应真身中的ServletConfig
  • session(HttpSession)
  • pageContext,一个顶九个
  • application(ServletContext)

servlet三大域对象,jsp四大域对象。

  • ServletContext,作用于整个应用程序
  • session,整个会话,一个会话只有一个用户
  • request,一次请求,一个请求可能跨多个servlet
  • pageContext,一个jsp页面,在当前页面和当前页面所使用的标签之间共享数据。

    1、代理其它域;
    pageContext.setAttribute(“xxx”,”XXX”,PageContext.PAGE_SCOPE);
    2、全域查找;
    pageContext.findAttribute(“xxx”);从范围较小的域查到范围大的域,小域优先于大域
    3、获取其它域对象

jsp动作标签

动作标签是由服务器来执行的,而静态的html是由浏览器的解释的。

jsp:forward 请求转发
jsp:include 动态包含,在运行的时候调用另一个页面。与<%@include>不同。
jsp:param 作为include和forward的子标签,用来给转发和包含的页面传值。

JavaBean规范

1、必须要有一个默认构造器
2、提供get/set方法,如果只有get方法,那么这个是可读属性
3、属性:有get/set方法的成员,还可以没有成员。属性名称由get/set方法来决定,即get/set方法名称去掉get/set后小写的名称。

EL表达式

EL是jsp内置的表达式语言。
作用:

  • 替代<%= … %>,也就是说,EL是用来输出的
  • 读取四大域对象,${xxx},全域查找名为xxx的属性,如果不存在就输出空串而不是null。${pageScope.xxx}、${requestScope.xxx}、${sessionScope.xxx}、${applicationScope.xxx},指定域获取属性。
  • javaBean导航,${requestScope.emp.address.street},使用El获取request域的emp —-> request.getAttribute(“emp”).getAddress().getStreet()。

EL函数库

1
2
3
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

${fn:toLowerCase("Hellowosdio")}

jstl

core库

out标签
1
2
3
4
5
<%
request.setAttribute("code","<script>alter('helloworld');</script>");
%>
${code}
<c:out value="${code}" />
set标签
1
2
<c:set var="name" value="<script>alter('helloworld');</script>" scope="request"/>
<c:out value="${name}" />

重要属性:scope:默认为page,可选值为page,request,session,application。

remove标签

如果不写scope,那么删除的全域中所有的属性

url标签

value属性:指定一个路径名,自动在路径前面添加项目名。

注意:路径名必须以斜杠开头

1
2
<c:url value="/Aservlet" />
//在页面上输出/jsp/Aservlet

1
2
3
4
<c:url value="/Aservlet" >
<c:param name="name" value="gageshan" />
</c:url>
// 输出为 jsp/Aservlet?name=gageshan

重要属性:var:指定变量名,添加这个属性后,url标签就不会输出到页面中,而是会保存到域中。
scope:与var一起使用,将url标签保存到域中。

if、choose

if对应Java中的if语句,choose对应Java中的if/else if/else

1
2
3
<c:if test="11>4">
<c:out value="/a"/>
</c:if>
1
2
3
4
5
6
<c:choose>
<c:when test=""></c:when>
<c:when test=""></c:when>
<c:when test=""></c:when>
<c:otherwise></c:otherwise>
</c:choose>
foreach

用来循环遍历数组,集合。

1
2
3
4

<c:forEach var="i" begin="1" end="10" step="1">
${i}
</c:forEach>

重要的属性:items:指定要循环谁,可以是数组或者集合,items=”${…}”,不能写有空格。var:将数组或集合中的元素赋给var指定的变量。varStatus,循环状态变量。

fmt

格式化库

格式化日期

<fmt:formatDate value=”” pattern=””>

value:指定一个Date类型变量
pattern:指定输出的模板,”yyyy-mm-dd HH:mm:ss”

格式化数字

<fmt:formatNumber value=”${num1}” pattern=”0.00” />
pattern:0.00:保留小数点后两位,不足两位以0来补,并且会四舍五入。#.##,不补位。

自定义标签

写标签类:

1
2
3
4
5
6
7
8
9
10
11
12
13
package web.day3_2;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;

public class MyTag1 extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
this.getJspContext().getOut().write("hello tag");
}
}

配置tld文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="ISO-8859-1"?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">

<tlib-version>1.0</tlib-version>
<short-name>itcast</short-name>
<uri>http://www.itcast.cn/tags/it-1.0</uri>

<!-- Invoke 'Generate' action to add tags or functions -->
<tag>
<name>mytag1</name>
<tag-class>web.day3_2.MyTag1</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>

-------------本文结束感谢您的阅读-------------
0%