Javaweb见解2
7 重定向和转发
web网站上面有一些跳转按钮。比如登录成功以后跳转到主页面!!!
7.1 重定向
- 是什么
用户通过浏览器发送一个请求,Tomcat服务器接收这个请求,会给浏览器发送一个状态码302,并设置一个重定向的路径,浏览器如果接收到了这个302的状态码以后,就会去自动加载服务器设置的路径
一个页面跳转到另外一个页面(应用场景)、登录页面跳转到主页面:
login.jsp====>LoginServlet====>main.jsp
- 特征:
①重定向的过程是浏览器(客户端)的行为
②实际上浏览器做了2次请求(当点击登录按钮的时候做了两次请求)(分别是请求login和main.jsp)
③注意上一次请求的request对象会丢失
④重定向有一个非常明显的特征,即浏览器的url变化了 - 重定向就一句核心代码:
response.sendRedirect("main.jsp"); //就这一行代码,但是这一行代码必须写在doGet或者doPost方法中
- login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--请求RedirectServlet--%>
<form action="redirect" method="post">
<input type="text" name="username"/><br>
<input type="text" name="password"/><br>
<input type="submit" value="提交">
</form>
</body>
</html>
- RedirectServlet
package com.by.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置字符编码
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
request.setAttribute("username", username);
request.setAttribute("password", password);
//登录以后跳转到主页
//重定向
//这个TestLoginServlet里面的数据是不能传给target.html的
response.sendRedirect("main.jsp");
}
}
- web.xml
<servlet>
<servlet-name>redirect</servlet-name>
<servlet-class>com.by.servlet.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>redirect</servlet-name>
<url-pattern>/redirect</url-pattern>
</servlet-mapping>
- main.jsp
xxxxxxxxxx <%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body>这是main页面<br><%--<%=request.getAttribute("username")%><%=request.getAttribute("password")%>--%>?${username}${password}</body></html>
- 测试
7.2 转发
- 是什么
用户发送数据请求到服务器,服务器接收当前请求,会调用内部方式(转发)处理该请求,最终把响应给客户端 - 特征:
①转发是服务器的行为
②浏览器在这个过程中只有一次行为
③转发可以带有数据 request对象中
④url不会发生任何的变化 - 核心代码也只有一行
request.getRequestDispatcher(“main.jsp”).forward(request,response);
//这一行代码就表示进行了转发,url没有变,但是响应的结果却是一次请求干了两个活
- login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--请求ForwardServlet--%>
<form action="forward" method="post">
<input type="text" name="username"/><br>
<input type="text" name="password"/><br>
<input type="submit" value="提交">
</form>
</body>
</html>
- ForwardServlet
package com.by.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ForwardServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置字符编码
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
request.setAttribute("username", username);
request.setAttribute("password", password);
//登录以后跳转到主页
//重定向
//这个TestLoginServlet里面的数据是不能传给target.html的
request.getRequestDispatcher("main.jsp").forward(request, response);
}
}
- web.xml
<servlet>
<servlet-name>forward</servlet-name>
<servlet-class>com.by.servlet.ForwardServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>forward</servlet-name>
<url-pattern>/forward</url-pattern>
</servlet-mapping>
- main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
这是main页面<br>
${username}
${password}
</body>
</html>
- 测试
8 Servlet的自动加载
默认情况下,第一次访问servlet的时候,创建servlet对象。如果servlet构造函数里面的代码或者init方法里面的代码比较多,就会导致用户第一次访问servlet的时候比较慢。这个时候,我们可以改变servlet对象的创建时机:提前到加载web应用的时候。在servlet的配置信息中,加上一个<load-on-startup>
标签即可。
<servlet>
<servlet-name>loadOnStartup</servlet-name>
<servlet-class>com.by.servlet.LoadOnStartupServlet</servlet-class>
<!--容器是否在启动时加载该servlet,数字越小优先级越高越高-->
<load-on-startup>1</load-on-startup>
</servlet>
servlet实例:
public class LoadOnStartupServlet implements HttpServlet {
public LoadOnStartupServlet(){
System.out.println("LoadOnStartupServlet constructor method has run....");
}
}
这样配置之后,servlet的构造函数和init方法就会在web应用加载的时候就会执行。
9 ServletConfig对象
-
是什么
ServletConfig是javax.servlet.包下的一个接口,ServletConfig它是Servlet的一个配置对象;
ServletConfig是由tomcat容器创建,通过init方法传入给Servlet;
-
ServletConfig对象如何获取?
在GenericServlet里面定义了:
public ServletConfig getServletConfig() {
return this.config;
}
- 常用方法
getInitParameter(String parameterName); //根据参数名称获取指定的参数值
getInitParameterNames(); //获取所有的参数名称
- 需求:
获取servlet里面定义的参数
<servlet>
<servlet-name>servletConfig</servlet-name>
<servlet-class>com.by.servlet.ServletConfigServlet</servlet-class>
<!--Servlet的初始化参数-->
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>root123</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servletConfig</servlet-name>
<url-pattern>/servletConfig</url-pattern>
</servlet-mapping>
package com.by.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
public class ServletConfigServlet extends HttpServlet {
@Override
public void service(ServletRequest servletRequest,
ServletResponse servletResponse) throws ServletException {
//1.获取ServletConfig对象
ServletConfig servletConfig = getServletConfig();
//2.获取Servlet中的初始化参数
String username = servletConfig.getInitParameter("username");
System.out.println(username);
String password = servletConfig.getInitParameter("password");
System.out.println(password);
}
}
思考:param参数可不可以在另外的Servlet中获取? 不能
public class ServletConfigServlet2 extends HttpServlet {
@Override
public void goGet(ServletRequest servletRequest,
ServletResponse servletResponse) throws ServletException {
//1.获取ServletConfig对象
ServletConfig servletConfig = getServletConfig();
//2.获取Servlet中的初始化参数
String username = servletConfig.getInitParameter("username");//不能获取
System.out.println(username);
String password = servletConfig.getInitParameter("password");//不能获取
System.out.println(password);
}
}
10 ServletContext对象
-
是什么
ServletContext是javax.servlet包下的一个接口,又称上下文对象,是配置对象也是一个域对象;
当服务器启动时,会为服务器中的每一个web应用程序创建一个ServletContext对象;
在web应用中的servlet要想实现资源的共享,可以通过ServletContext来完成;
-
如何获取这个对象:
public ServletContext getServletContext() {
//获取ServletContext对象
return this.getServletConfig().getServletContext();
}
- 这个对象里面也有很多方法:
getInitParameter() //获取指定参数名称的全局参数值
getRealPath(String path) //获得当前项目的服务器磁盘路径
getContextPath() //获取项目的根路径
getAttribute(String parameterName) //获取ServletContext域中指定名称的参数值;
setAttribute(String paramterName,Object parameterValue) //存储参数到ServletContext域中;
removeAttribute(String parameterNam) //将ServletContext域中指定名称的参数移除;
- 需求
获取servlet里面定义的参数
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root456</param-value>
</context-param>
package com.by.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
public class ServletContextServlet extends HttpServlet {
@Override
public void service(ServletRequest servletRequest,
ServletResponse servletResponse) throws ServletException {
//获取ServletContext对象
ServletContext servletContext = getServletContext();
//1.获取全局初始化参数
String username = servletContext.getInitParameter("username");
System.out.println(username);
String password = servletContext.getInitParameter("password");
System.out.println(password);
//2.获取服务器真实路径
String upload = servletContext.getRealPath("");
System.out.println(upload);
//3.获取项目的根路径
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
//4.往ServletContext域中,存储一个名称为msg的属性,值为"hello"
String str = "hello";
servletContext.setAttribute("msg",str);
}
}
思考:param参数可不可以在另外的Servlet中获取? 不能
package com.by.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
public class ServletContextServlet2 extends HttpServlet {
@Override
public void doGet(ServletRequest servletRequest,
ServletResponse servletResponse) throws ServletException {
//从ServletContext域中取出msg的值
ServletContext servletContext = getServletContext();
//1.获取全局初始化参数
String username = servletContext.getInitParameter("username");
System.out.println(username);
String password = servletContext.getInitParameter("password");
System.out.println(password);
//2.获得msg属性
Object msg = servletContext.getAttribute("msg");//能获取
System.out.println(msg);
}
}
package com.by.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
public class ServletContextServlet3 extends HttpServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException {
//1.获取ServletContext对象
ServletContext servletContext = getServletContext();
//将ServletContext域中的msg参数移除
servletContext.removeAttribute("msg");
}
}
<servlet>
<servlet-name>context3=</servlet-name>
<servlet-class>com.by.servlet.ServletContextServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>context3=</servlet-name>
<url-pattern>/context=</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>context2</servlet-name>
<servlet-class>com.by.servlet.ServletContextServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>context2</servlet-name>
<url-pattern>/context2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>context3</servlet-name>
<servlet-class>com.by.servlet.ServletContextServlet3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>context3</servlet-name>
<url-pattern>/context3</url-pattern>
</servlet-mapping>
11 Request对象
- 是什么
ServletRequest是一个接口,用户访问服务器,服务器会生成一个对象包含了http所有请求头,由于使用的是http协议,所以该对象的名字叫HttpServletRequest
- 常用的方法
getRequestURL() //获取的完整的URL,即统一资源定位符
getRequestURI() //获取资源的名字,即统一资源标识符
getQueryString() //获取一个url参数部分
getRemoteAddr() //返回的是客户端的ip地址
getRemoteUser() //返回的是客户端的用户
getRemotePort() //返回的是客户端的主机的端口号
getRemoteHost() //返回的是客户端的主机地址
getCookie() //获取Cookie对象
getSession() //获取Session对象
getLocalName() //获取Web服务器主机的名字
getServletContext() //获取上下文对象的
setCharacterEncoding() //设置编码集的
getParameter() //获取前端传过来的数据
setAttribute() //将数据设置给request对象
geAttribute() //获取request对象中的数据
- servlet实例
package com.by.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws Exception {
doGet(request, response);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws Exception{
//获取一个完整的url
//http://localhost:8080/01_servlet_HelloWorld_war/request1
System.out.println(request.getRequestURL());
//获取资源的名字
//比如:http://localhost:8080/day42_xkh/request1
System.out.println(request.getRequestURI());///01_servlet_HelloWorld_war/request1
//获取一个url的参数部分
//比如 http://localhost:8080/01_servlet_HelloWorld_war/request1?username=goudan
System.out.println(request.getParameter("username"));
//获取前端传送过来的数据
request.setCharacterEncoding("utf-8");//设置请求的编码集
//给request这个对象设置数据
request.setAttribute("name","狗蛋");
//获取request对象的值
request.getAttribute("name");
//获取上下文对象
ServletContext servletContext = request.getServletContext();
//转发
request.getRequestDispatcher("target.jsp").forward(request,response);
}
}
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.by.servlet.RequestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>
12 Response对象
- 是什么
响应对象,把数据返回给客户端
我们的Servlet紧紧围绕着两个点(Request,Response)请求和响应
- 常用方法
setHeader() //设置响应头的参数
setContentType() //设置字符编码集
getWriter() //获取字符输出流对象
addCookie() //对浏览器新增一个Cookie
sendRedirect() //重定向
- servlet实例
package com.by.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ResponseServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws Exception{
/**************乱码问题*****/
//方式一
response.setHeader("Content-Type",
"text/html;charset=utf-8");//通知浏览器使用utf-8解码
//方式二
response.setContentType("text/html;charset=utf-8;aaa=bbb"); //包含方法一的两个功能
//向客户端发送响应数据
response.getWriter().write("<h1>hello<h1>");
/************重定向***********/
//方式一
//在响应头中添加302状态码,告诉浏览器需要进行重定向
response.setStatus(302);
//在响应头中添加Location,指定重定向的位置
response.setHeader("Location", "http://www.baidu.com");
//方式二
response.sendRedirect("http://www.baidu.com"); //包含方法一的两个功能
}
}
<servlet>
<servlet-name>response</servlet-name>
<servlet-class>com.by.servlet.ResponseServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>response</servlet-name>
<url-pattern>/response</url-pattern>
</servlet-mapping>
13 Cookie和Session
http协议是一个无状态的协议,你每一个跳转到下一个页面的时候都是需要先登录才能使用,这样就很麻烦比如淘宝,没有cookie和session的话,用户在首页已经登录上去了,但是需要再次登录才能选择商品,需要再次登录才能放到购物车,需要再次登录才能然后购买,这样用户的体验是相当差的。
13.1 cookie
- 是什么
-
cookie是在浏览器中保存的
-
如果想要使用cookie要保证我们的浏览器是开启cookie,所以说有一定的弊端,如果浏览器没有开启cookie,就不能再使用cookie了
-
cookie的大小是有限制的,通常是4096byte
-
cookie的保存是以键值对的形式存在的
- 常用方法
//1.cookie的构造方法,目的是实例化出来cookie对象
Cookie(String name,String value)
//2.设置cookie的方法
setValue(String value) //修改cookie的值
getValue(String value) //获得cookie的值
getName(String value) //获得cookie的键
setMaxAge(int time) //设置cookie的有效时间
//3.要将cookie发送到浏览器
response.addCookie(Cookie cookie);
//4.获得所有cookie
request.getCookies();
- servlet实例一
package com.by.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SetCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws Exception {
/**
* 1.创建cookie对象
* 将键:msg 值:sb ,存到cookie对象中
*/
Cookie cookie = new Cookie("msg", "sb");
/**
* 2.设置有效时间
* 正数:表示当前cookie的有效时间
* 负数:表示当前浏览器打开的时候存在,关闭的时候没了
* 0:销毁当前的cookie
*/
cookie.setMaxAge(60*60*24);//设置了有效期是个正数,
//3.把cookie发送到浏览器
response.addCookie(cookie);
}
}
<servlet>
<servlet-name>setCookie</servlet-name>
<servlet-class>com.by.servlet.SetCookieServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>setCookie</servlet-name>
<url-pattern>/setCookie</url-pattern>
</servlet-mapping>
- servlet实例二
package com.by.servlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//获取浏览器中cookie,返回值是一个数组
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println("==============");
System.out.println(cookie.getName());//获取键
System.out.println(cookie.getValue());//获取值
}
}
}
<servlet>
<servlet-name>getCookie</servlet-name>
<servlet-class>com.by.servlet.GetCookieServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getCookie</servlet-name>
<url-pattern>/getCookie</url-pattern>
</servlet-mapping>
- 实例三
@WebServlet("/destroyCookie")
public class DestroyCookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//退出登录
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("msg")){
cookie.setMaxAge(0);//销毁cookie
//重新发送给浏览器
response.addCookie(cookie);
}
}
}
}
<servlet>
<servlet-name>destroyCookie</servlet-name>
<servlet-class>com.by.servlet.DestroyCookieServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>destroyCookie</servlet-name>
<url-pattern>/destroyCookie</url-pattern>
</servlet-mapping>
13.2 session
- 为什么使用session?
- cookie保存数据类型是单一的,只能保存字符串类型的数据
- cookie的大小有限制
- 是什么?
保存服务器中
当用户发送一个HTTP请求到服务器时,服务器会检查该请求是否包含session标识符(通常是存cookie),如果没有,则会创建一个新的session(存储区域),并将session标识符发送给客户端。浏览器再发送请求时会携带session标识符,此时服务器根据session标识符就可以找到对应的session(存储区域)
使用session的时候一般要开启cookie如果浏览器没有开启cookie功能,我们可以通过html的url传参完后session的使用
没有大小的限制
信息的保存也是以键值对的形式存在的
- 常用方法
request.getSession(true); //返回HttpSession
setAttribute(key,value); //设置属性 key ,value
getAttribute(key); //获取key的值
removeAttribute(String key) //通过key值删除数据
invalidate(); //将session中的变量全部清空
setMaxInactiveInterval(int interval); //设置session失效时间,单位为秒
getMaxInactiveInterval();//获取session失效时间
getId(); //获取sessionID
- 实例一
package com.by.servlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
public class SetSessionServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//1.获取session对象
HttpSession session = request.getSession();
System.out.println(session);
//获取的是JSESSIONID 服务器唯一的标识
System.out.println(session.getId());
//给session设置一个时间,有效果的,里面放的是秒
session.setMaxInactiveInterval(60*60*24);
User user = new User();
user.setUsername("张5丰");
user.setBirthday(new Date());
user.setSex("1");
session.setAttribute("user",user);
}
}
<servlet>
<servlet-name>setSession</servlet-name>
<servlet-class>com.by.servlet.SetSessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>setSession</servlet-name>
<url-pattern>/setSession</url-pattern>
</servlet-mapping>
- 实例二
package com.by.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class GetSessionServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//1.获取Session对象
//第一次创建session的时候默认为true
//false的话,这个session使用的是已经创建好的session对象
HttpSession session = request.getSession(false);
//2.获取session,通过键取值
Object user = session.getAttribute("user");
System.out.println(user);
}
}
<servlet>
<servlet-name>getSession</servlet-name>
<servlet-class>com.by.servlet.GetSessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getSession</servlet-name>
<url-pattern>/getSession</url-pattern>
</servlet-mapping>
- 实例三
package com.by.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class DestroySessionServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//1.获取session对象
HttpSession session = request.getSession();
//销毁当前的session
session.invalidate();
}
}
<servlet>
<servlet-name>destroySession</servlet-name>
<servlet-class>com.by.servlet.DestroySessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>destroySession</servlet-name>
<url-pattern>/destroySession</url-pattern>
</servlet-mapping>
14 过滤器和监听器
14.1 过滤器
- 什么是过滤器
当浏览器向服务器发送请求的时候,过滤器可以将请求拦截下来,完成一些特殊的功能,比如:编码设置、权限校验、日志记录等。
- 过滤器执行流程
- Filter实例
package com.by.servlet;
import javax.servlet.*;
import java.io.IOException;
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//真正执行过滤业务的方法
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");//设置请求的编码格式
response.setContentType("text/html;charset=utf-8"); //设置相应的编码格式
System.out.println("请求进来,经过过滤器...");
//一个web路径,可以配置多个过滤器,这多个过滤器就被称为过滤器链
filterChain.doFilter(request,response);
System.out.println("相应返回,经过过滤器...");
}
@Override
public void destroy() {
}
}
- 使用过滤器需要注意的事项:
1.过滤器必须实现Filter接口。
2.过滤器拦截的请求执行完毕之后,必须要放行,否则我们的请求就不会被执行。
filterChain.doFilter(request,response); //过滤器放行
3.我们可以使用@WebFilter来配置过滤器要拦截的资源,当然我们也可以通过xml的方式配置过滤器。
<filter>
<filter-name>filter</filter-name>
<filter-class>com.by.servlet.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- Filter的拦截路径的配置
1.拦截具体的资源路径:/index.jsp,只有访问index.jsp的时候才会被拦截
2.目录拦截:/user/*,访问/user下的所有资源,都会被拦截
3.后缀名拦截:*.jsp 访问后缀名为jsp的资源,都会被拦截
4.拦截所有:/* 访问所有的资源,都会被拦截
- 测试
1.创建servlet
package com.by.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class FilterTestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//设置字符编码
//request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username: " + username+"===password"+password);
//设置字符编码
//response.setContentType("text/html;charset=utf-8");
response.getWriter().write("username: " + username+"===password"+password);
}
}
2.配置servlet
<servlet>
<servlet-name>filterTest</servlet-name>
<servlet-class>com.by.servlet.FilterTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>filterTest</servlet-name>
<url-pattern>/filterTest</url-pattern>
</servlet-mapping>
3.创建filter_test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="filterTest" method="post">
<input type="text" name="username"/><br>
<input type="text" name="password"/><br>
<input type="submit" value="提交">
</form>
</body>
</html>
14.2 监听器
- 是什么?
监听器可以监听就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。
- Listener分类:Javaweb提供了8个监听器(接口)
- listen实例
package com.by.servlet;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyListener implements ServletContextListener {
//监听Servlet上下文对象创建的方法
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("============tomcat启动(create servletContext)========");
}
//监听Servlet上下文对象销毁的方法
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("============tomcat关闭(destroyed servletContext)==========");
}
}
<!--配置监听器-->
<listener>
<listener-class>com.by.listen.MyListener</listener-class>
</listener>
15 web三层架构
三层架构就是把整个软件的代码分为三个层次,分层的目的是:
- 解耦,即在开发软件时对每个层的代码进行规范,忽略数据库差异,当软件系统要换数据库时,只要将数据访问层的代码修改就好了。
2. 规范代码,大型软件需要团队配合的时候问题就来了,由于每个程序员风格不一样,而开发软件大量的代码风格不统一就会造成后期调试和维护出现问题,然而软件分层后,每个层合理分工这样的问题便迎刃而解
-
web层
com.by.web/servlet/controller:servlet包,接受请求控制跳转页面
-
service 层
com.by.service:Service接口包
com.by.service.impl:Service接口实现类,处理业务
-
dao 持久层
com.by.dao:Dao接口包
com.by.dao.impl: Dao接口实现类,访问数据库
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!