Servlet(三层架构思想)

1、Servlet概述

servlet是一种独立于平台和协议的服务器端的java应用程序,通过Servlet可以生成动态的Web页面。

同时,使用Servlet还可以在服务器端对客户端的请求进行处理,控制程序的执行。Servlet的主要作用就是交

互式的浏览和更新数据

2、Servlet的生命周期

tomcat启动的时候默认不会帮我们创建servlet,当第一次请求过来的时候tomcat帮我们创建servlet对象,

之后所有该servlet的请求共用同一个servlet对象(在servlet里面最好不要使用全局变量)

生命周期四个阶段:

实例化:servlet容器创建Servlet的实例

初始化:该容器调用init()方法

提供服务,请求处理:如果请求Servlet,容器调用service层方法处理请求

销毁:销毁实例之前调用destory()方法(destroy方法指明哪些资源可以被系统回收,而不是由destroy()方

​ 法直接进行回收)

3、怎么通过URL访问Servlet

1、编写一个类,该类必须继承HttpServlet

2、重写doGet()以及doPost()方法 (doGet()方法处理get请求,doPost()方法处理post请求,所以在doPost()

​ 方法中调用doGet()方法即可)

3、在web.xml里面给servlet配置请求路径(web.xml该配置文件中可以对整个应用进行全局配置,tomcat加

​ 载该项目是首先读取的就是该配置文件)

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>newsServlet</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置开始 -->
<servlet>
<!-- 命名习惯:Servlet类的类名首字母小写 -->
<servlet-name>userLoginServlet</servlet-name>
<!-- Servlet类的全路径 -->
<servlet-class>com.wanglei.servlet.UserLoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userLoginServlet</servlet-name>
<!-- 访问路径:http://localhost:8080/项目名/userLoginServlet.do -->
<url-pattern>/userLoginServlet.do</url-pattern>
</servlet-mapping>
<!-- 配置结束 -->
</web-app>

还可通过注解方式使用Servlet,这种方式使用不用手动配置,直接右键new–>Servlet

4、Servlet中怎么获取表单数据

1
2
//获取表单中的密码password
String password = request.getParameter("password");

5、如何操作四大作用域

1、获取session作用域:request.getSession()

2、获取application作用域:

​ 通过父类提供的方法获取:request.getServletContext()

​ 通过session获取:request.getSession().getServletContext()

6、如何跳转页面

学到哪都两种跳转方式:请求转发:request.getRequestDispatcher(“跳转页面名”)

​ 重定向:response.sendRedirect(“跳转页面名”);

7、过滤器

一般用途就两种:字符编码过滤器和用户是否登录过滤器

1、字符编码过滤器

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
package com.wanglei.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CharSetFilter implements Filter{
//首先创建一个类实现Filter接口,重写里面的三个方法

//销毁的方法,仅执行一次
@Override
public void destroy() {
System.out.println("字符编码过滤器销毁了。。。");
}

//拦截执行的具体方法
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
//将argo,arg1强转为HttpServletRequest,HttpServletResponse
HttpServletRequest request = (HttpServletRequest)arg0;
HttpServletResponse response = (HttpServletResponse)arg1;
//设置字符编码格式
request.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
//放行请求
arg2.doFilter(request, response);
//System.out.println("拦截了"+request.getContextPath()+request.getServletPath());
}

//创建的时候执行的方法,仅执行一次
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("字符编码过滤器创建了。。。");
}

}

注意:在web.xml文件中配置过滤器(千万别忘记)

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>newsServlet</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>

<!-- 配置字符编码过滤器开始 -->
<filter>
<!-- 字符编码过滤器名字 -->
<filter-name>charSetFilter</filter-name>
<!-- 字符编码过滤器类的全路径 -->
<filter-class>com.wanglei.filter.CharSetFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>charSetFilter</filter-name>
<!-- 过滤器要过滤哪些类型 -->
<url-pattern>*.do</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- 配置字符编码过滤器结束 -->

<!-- 配置是否登录过滤器开始 -->
<filter>
<filter-name>userIsNoLoginFilter</filter-name>
<filter-class>com.wanglei.filter.UserIsNoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>userIsNoLoginFilter</filter-name>
<url-pattern>*.do</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- 配置是否登录过滤器结束 -->

<servlet>
<servlet-name>userLoginServlet</servlet-name>
<servlet-class>com.wanglei.servlet.UserLoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userLoginServlet</servlet-name>
<url-pattern>/userLoginServlet.do</url-pattern>
</servlet-mapping>
</web-app>

2、是否登录过滤器

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
package com.wanglei.filter;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wanglei.pojo.User;

public class UserIsNoLoginFilter implements Filter{

@Override
public void destroy() {
System.out.println("用户是否登录拦截器销毁了。。。");
}

@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
//将arg0,arg2强转为HttpServletRequest,HttpServletResponse
HttpServletRequest request = (HttpServletRequest)arg0;
HttpServletResponse response = (HttpServletResponse)arg1;
//取出session中数据
User loginUser= (User)request.getSession().getAttribute("loginUser");
//动态拼接绝对路径
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
String path = request.getServletPath();
//System.out.println("拦截了"+path);
//判断登录用户是否为空和要放行的情况
if(loginUser!=null || "/login.jsp".equals(path) || "/userLoginServlet.do".equals(path) || "/register.jsp".equals(path) || "/registerNameServlet.do".equals(path)) {
arg2.doFilter(request, response);
}else {
response.sendRedirect(basePath+"login.jsp?error="+URLEncoder.encode("未登录,请求非法!!!", "utf-8"));
}
}

@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("用户是否登录拦截器创建了。。。");
}

}

8、EL表达式和jstl标签(C标签)

利用这两个来消除JSP页面的JAVA代码,提高代码的阅读性

8.1.EL表达式

EL表达式:负责从各种作用域中取值,以及一些简单的运算

1.取四大作用域值:${requestScope.req },如果省略作用域名称那么默认先从最小作用域中搜索,找到输出

2.取list集合:${news }

3.取list集合第二个元素:${news[1]}

4.取list集合第二个元素的title属性:${news[1].title} 直接写属性名称即可,不用get方法

5.取表单数据:${param.pg} 一定要用param.表单元素名

6.取cookie数据:${URLDecoder.decode(cookie.nameCookie.value,’utf-8’)}

​ 格式为cookie.Cookie名字.value

7.一些运算:+ - * /

​ || && !

8.2.jstl标签(C标签)

1.导入jstl的jar包

2.在页面引入c标签库:

1
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

常用标签:

1
2
3
4
5
6
<c:out>标签用来显示数据,类似于<%=%>输出方式,但是可以进行选择性转义输出和设置默认值

语法:<c:out value="需要输出显示的表达式" default="为空时默认值" escapeXml="true|false"/>
escapeXml:是否转义输出

注意:<c:out>标签输出显示前,需要将数据放到作用域内
1
2
3
4
5
6
7
8
<c:set>标签用来对作用域内容的变量或者对象属性进行设置

<c:set>标签设置变量的语法:
<c:set value="变量的值" var="变量的名称" scope="作用域范围"/>
作用域范围为page/request/session/application中的一个

<c:set>标签设置对象属性的语法:
<c:set value="属性的值" target="对象的名称" property="对象属性的名称"/>
1
2
3
4
5
<c:remove>标签用来移除作用域范围内的变量

语法:<c:remove var="变量名" scope="作用域范围"/>

注意:<c:set>和<c:remove>中的var和scope不能接受动态的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<c:forEach>标签用来迭代输出,类似于foreach循环

语法:<c:forEach var="集合名称" items="集合对象" [varStatus="当前循环状态"]>...</c:forEach>

比如遍历新闻列表:
<c:forEach items="${newsList }" var="news">
<tr align="center">
<td><input type="checkbox" name="subCheckbox" value="${news.id }"></td>
<td>${news.newsid }</td>
<td>${news.title }</td>
<td>${news.context }</td>
<td>${news.newsman }</td>
<td><fmt:formatDate value="${news.newsdate }" pattern="yyyy-MM-dd"/></td>
<td><img src="${news.pic }"></td>
</tr>
</c:forEach>
1
2
3
<c:if>标签类似于if单分支选择

语法:<c:if test="判断条件" [var="判断的结果名" scope="判断结果存放的作用域"]>...</c:if>
1
2
3
4
5
6
7
8
9
10
<c:choose>标签类似于多分支选择结构if-else if -else
例如:
<c:choose>
<c:when test="${fy.page==fy.pageCount }">
下一页
</c:when>
<c:otherwise>
<a href="#">下一页</a>
</c:otherwise>
</c:choose>
1
2
3
4
5
6
7
8
9
10
动态拼接URL标签
<c:url value="toMainServlet.do" var="toMainURL" scope="request">
<c:param name="title" value="${fy.lq.lqTitle }"></c:param>
<c:param name="startDate">
<fmt:formatDate value='${fy.lq.lqStartDate }' pattern='yyyy-MM-dd'/>
</c:param>
<c:param name="endDate">
<fmt:formatDate value='${fy.lq.lqEndDate }' pattern='yyyy-MM-dd'/>
</c:param>
</c:url>
1
2
3
4
5
6
7
8
格式化日期

首先加入包:<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

语法:<fmt:formatDate value="date" pattern="yyyy-MM-dd"/>

例如:
<fmt:formatDate value='${fy.lq.lqStartDate }' pattern='yyyy-MM-dd'/>

9、相对路径和绝对路径

绝对路径:http://localhost:8090/项目名/资源路径

相对路径:如果jsp页面有<%=basePath%>那么页面上的所有路径相对于项目根目录,如果没有

<%=basePath%>相对于访问该资源的路径(就是浏览器地址栏显示的路径)拼相对路径,在过滤器中的相对路径,

相对于该过滤器拦截到的请求

ADD

servlet 工作工作过程和原理

  1. 将 webapps 下的每个子文件夹发布为一个网站
  2. 读取每个网站的WEB-INF/web.xml配置文件, 获取每个网站对应的servlet类(类和对应的url地址),如果Servlet 类配置中有 , 创建servlet对象

Servlet 类的对象的创建

  • 由 tomcat 服务器来创建
  • 创建时间
    1. 当配置时有 :服务器启动时
    2. 没有 : 第一个请求对应地址时
  • 创建对象个数:只有一个, Servlet 为单例对象
    Servlet 类是线程不安全的, 所以要避免给 Servlet 类定义属性

Tomcat 启动过程

  1. 扫描 webapps 下面的所有网站

  2. 读取每个网站的 web.xml 获取 Servlet 类和对应的地址, 合并 conf/web.xml 中的 Servlet 类, 得到表格:

网站 地址 Servlet类
通用 ×.jsp jspServlet
自定义Servlet web.xml 映射的地址 自定义Servlet
通用 / DefaultServlet

Tomcat 的请求处理过程

  1. 创建请求对象 request 和配套的响应对象 response, 将请求数据包中的数据封装到request请求的对象中

  2. 找到 servlet 类:按本次请求的地址到启动过程中建立的表格中一一对比, 找到 Servlet 对象

  3. 得到 Servlet 对象: 判断 Servlet 对象是否存在, 如果不存在, 则创建新的 Servlet 对象

  4. 调用 Servlet 对象的 doGet/doPost方法处理请求

Servlet开发过程中常用的内置对象

  1. tomcat服务器已经创建的对象,我们直接使用就OK

  2. request:请求对象,封装了请求数据包中的数据

  3. response:响应对象,保存处理过程中产生的结果

  4. servletConfig:初始化参数对象,保存配置文件中servlet配置中的初始化参数. 初始化参数配置在servlet中,适用于指定的servlet

    1. servletContext:上下文对象,域对象,保存配置文件中配置的初始化参数. 初始化参数配置在servlet之外,适用于所有的servlet
------ end ------