Java Web(二)

1 重定向和EL表达式

1.1 RequestDispatcher 请求转发

  • RequestDispatcher 请求转发

    • 客户端发起请求,servlet处理业务逻辑;
    • servlet调用forward方法,把请求转发到指定资源(jsp、servlet、html);
    • 因为是内部转发所以地址栏的地址不会有变化;
      在这里插入图片描述
  • RequestDispatcher 可以访问WEB-INF的数据(有限制一般不能访问)

  • 示例:
    跳转的jsp代码

<%--Created by IntelliJ IDEA.User: 14408Date: 2022/12/7Time: 10:44To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Titletitle>
head>
<body>
我是跳转的dispatcher
body>
html>

java代码

package net.lizheng.web;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 java.io.IOException;
@WebServlet(name="dispatcher",value = "/dispatcherforward")
public class Dispatcher extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.getRequestDispatcher("WEB-INF/dispatcher.jsp").forward(req,resp);}
}

了解即可,

1.2 EL表达式

  • 全称Expression language 灵感来与ECMAscript和xpath ,提供了简写jsp的表达式,使jsp更加的简洁明了;
  • 语法:${变量名} 或者${对象.属性}
  • 取值是从小到大寻找page->request->session->application
    • 指定某个作用域寻找:
      • pageScope
      • requestScope
      • sessionScope
      • applicationScope
        javabean
package net.lizheng.web;public class User {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

jsp

<%--Created by IntelliJ IDEA.User: 14408Date: 2022/12/7Time: 10:44To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Titletitle>
head>
<body>
name1=${name1}
<br>
name2=${name3.name}
<br>
age=${name3.age}
<br>
<%--指定在session作用域寻找没有返回为空--%>
name3=${seessionScope.name2}
body>
html>

请求

package net.lizheng.web;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 java.io.IOException;
@WebServlet(name="dispatcher",value = "/dispatcherforward")
public class Dispatcher extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setAttribute("name1","小曾");req.setAttribute("name2","小政");User user=new User();user.setName("小小");user.setAge(12);req.setAttribute("name3",user);req.getRequestDispatcher("WEB-INF/dispatcher.jsp").forward(req,resp);}
}

1.3 sendRedirect 重定向

  • 重定向:客户端发送了请求,sevlet处理业务逻辑,servlet会调用sendRediect()方法会把目前资源(servlet,jsp,html,外部站点)作为响应信息返回给客户端,客户端会根据重定向的地址再次向服务器发送请求;
  • 不能访问web-inf目录,浏览器地址的地址会变化;
  • 原地址响应码为302 响应头location为跳转的新地址;
  • 外部站点必须加上http或者https才能访问;
  • 和requestdispatcher相比 sendredirect的性能效率不如requestdispatcher
    在这里插入图片描述
    代码
package net.lizheng.web;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 java.io.IOException;
@WebServlet(name = "sendRedirect",value = "/SendRedirecr")
public class SendRedirecr extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendRedirect("https://mp.csdn.net/");}
}

在这里插入图片描述

2 Session和Cookie

2.1 基础知识

  • 无状态协议:http是无状态协议,客户端和服务端交换数据结束,客户端和服务端就会断开连接,再次请求需要重新建立连接,这就意味着http不能记录http的状态。
  • 会话跟踪:会话是用户登录网站后的一系列的操作,例如登录视频网站查看视频,会话跟踪是web程序的一项技术,用来跟踪一个会话,常用的会话跟踪技术是session和cookie;
  • cookie是客户端记录信息验证身份,session是通过服务器记录信息验证身份;

2.2 Cookie

  • Cookie的工作原理:Cookie实际上是一小段文本信息,当服务器需要记录客户端请求状态的时候,服务端就会生成一个cookie发送给客户端,客户端会保存并在下一次请求附带这个cookie,服务端会校验cookie从而跟踪整个会话;
  • cookie的分类
    • 会话cookie 不设置有效期 生命周期是打开浏览器到关闭浏览器,储存在内存中;
    • 持久cookie 设置有效期 会把cookie存储在磁盘中;
  • cooke的常用的值
    • name 名字;
    • value 值 ;
    • domain 存储cookie的父域或者子域;
    • expired/max-age cookie的有效期;
    • size cookie的大小;
    • path cookie的路径;
    • http-only 客户端的cookie不能被客户端的js读取
    • secure 服务端只支持https的请求;
  • cookie的缺陷
    • 会增加请求的流量;
    • cookie以明文的方式不安全;
    • Cookie一般4000多k 不能存储大的数据;
    • 浏览器最多能支持50多个cookie 至少能支持20个;
      增加token代码
package net.lizheng.web.cookie;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;@WebServlet("/AddCookie")
public class AddCookie extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie cookie = new Cookie("token", "sdjlksjdlfjlsdjlfasjdkfjskldf");cookie.setMaxAge(200);cookie.setHttpOnly(true);resp.addCookie(cookie);}
}

在这里插入图片描述

获取token代码

package net.lizheng.web.cookie;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;
@WebServlet("/GetCookie")
public class GetCookie  extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie[] cookies = req.getCookies();for (Cookie cookie:cookies){System.out.println( "Name是"+cookie.getName());System.out.println( "Value是"+cookie.getValue());System.out.println( "Secure是"+cookie.getSecure());System.out.println("-----------------------");}}
}

在这里插入图片描述

2.3 Session

  • Session的工作原理:Session是记录客户状态的一种机制,Session是保存在服务端的,Session依赖Cookie,用户请求服务器会建立一个map结构的key-value的键值对(SessionId和Session),并把Sessionid(cookie)响应给客户端并保存,下次请求就会把SessionI携带过去,服务器收到SessionID就会检索从而达到记录客户状态;
  • Session有时效性,可以随着请求更改session的状态;
  • 登录举例
    登录JAVA代码
package net.lizheng.web.seession;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;@WebServlet("/Login")
public class Login extends HttpServlet{@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username =req.getParameter("username");String password =req.getParameter("password");if (username.equals("xiaozeng")&&password.equals("123456")){Userdemo userdemo=new Userdemo();userdemo.setName(username);userdemo.setAge(23);userdemo.setMsg("今天不学习明天变垃圾");HttpSession session = req.getSession();session.setAttribute("loginInfo",userdemo);req.getRequestDispatcher("WEB-INF//userinfo.jsp").forward(req,resp);}else {HttpSession session = req.getSession();session.setAttribute("errmsg","账号密码错误");req.getRequestDispatcher("/login.jsp").forward(req,resp);}//seeion的常用方法HttpSession session = req.getSession();System.out.println(session.getId());System.out.println(session.getCreationTime());System.out.println(session.isNew());}
}

退出JAVA代码

package net.lizheng.web.seession;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 java.io.IOException;@WebServlet("/Logout")
public class Logout extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//session失效req.getSession().invalidate();req.getRequestDispatcher("login.jsp").forward(req,resp);}
}

javabean代码

package net.lizheng.web.seession;public class Userdemo {private String name;private int age;private String msg;public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

登录页面信息

<%--Created by IntelliJ IDEA.User: 14408Date: 2022/12/8Time: 10:06To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Titletitle>
head>
<body>
<form action="/testdemo/Login" method="post"><input type="text" name="username"><br><input type="password" name="password"><br><input type="submit" value="登录">
form>
<br>
${errmsg}body>
html>

用户信息

<%--Created by IntelliJ IDEA.User: 14408Date: 2022/12/8Time: 10:30To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Titletitle>
head>
<body>
name=${loginInfo.name}
<br>
age=${loginInfo.age}
<br>
msg=${loginInfo.msg}
<br>
<a href="/testdemo/Logout"> 退出 a>body>
html>

3 Filter和Listener

3.1Filter

  • Filter是过滤器,会过滤servlet容器传给web资源的request对象和repone对象,进行检索和修改
  • Filter的作用:
    • 动态的拦截请求和响应,进行修改和使用请求和响应的信息;
    • 拦截请求是在进入web资源之前拦截;
    • 拦截响应会在响应客户端之前拦截;
  • Filter的生命周期(有三个方法):
    • init()方法,只会启动一次,用于初始化;
    • doFilter(HttpServletRuquest ruq,HttpServletRpone req ,FilterChain chain) 只要满足条件就会触发,只要根据条件决定是否放行(doChain()方法);
    • destroy 容器销毁的时候执行一次
  • @WebFilter注解:
方法描述
servletName以servletname为条件进行筛选 servletName等价于webServlet的Name
urlPatterns路径为筛选条件 等价于webServlet的urlPatterns
value和urlPatterns一样 两者不可一起使用,urlPatterns定义多个路径,value只能定义一个路径
filterName定义过滤器的名字
displayName过滤器的显示名字
dispatcherType过滤器筛选的范围
initparam初始化的参数
asyncSupported是否支持异步
decriptionFilter的描述信息
  • dispatcherType的筛选范围
    • REQUEST 默认值 监控所有的请求;
    • FORWARD 筛选forward方法的请求;
    • INCLUDE 筛选include方法的请求;
    • ERROR 错误资源的请求;
    • ASNYC 筛选异步请求;
  • FilterConfig的三个方法
public interface FilterConfig {//Filter的姓名String getFilterName();//获取ServletContext 对象ServletContext getServletContext();获取注解中初始化的参数String getInitParameter(String var1);Enumeration<String> getInitParameterNames();
}

3.2 Listener

  • 监听器是实现了特定接口的特殊类,用于监听对象创建和销毁以及对象的属性和对象方法的执行。
  • 作用监听域对象request/session/application:
    • ServletRquestListener
    • HttpSessionListener
    • ServletContextListener
  • 实现方法:
    • 创建一个普通类并实现接口;
    • 重写监听接口的方法 ;
    • 旧版Listener配置是在web.xml文件,新版是使用元注解;

3.2.1 SevletContextListener

  • 监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。
  • 例如:监听SevletContext的初始化参数:
    1.配置初始化参数

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><context-param><param-name>namelistenerparam-name><param-value>我是全局监听param-value>context-param><context-param><param-name>ageparam-name><param-value>web项目关闭自动销毁param-value>context-param>
web-app>

配置类

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><context-param><param-name>namelistener</param-name><param-value>我是全局监听</param-value></context-param><context-param><param-name>age</param-name><param-value>web项目关闭自动销毁</param-value></context-param>
</web-app>

建立监听类

package net.lizheng.web.Listener;import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;@WebListener
public class ServetAll implements ServletContextListener{@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("contextInitialized");ServletContext servletContext = sce.getServletContext();Config config=new Config();String name=servletContext.getInitParameter("namelistener");String age =servletContext.getInitParameter(("age"));config.setNamelistener(name);config.setAge(age);System.out.println(config.getNamelistener());System.out.println(config.getAge());}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("contextDestroyed");}
}

启动web项目
在这里插入图片描述

3.2.2 HttpSession

  • 监控整个session域对象。
  • 例如:统计用户在线人数量
    初始化全局变量
//设置session初始值
servletContext.setAttribute("onlineCount",0);

配置监听类

package net.lizheng.web.Listener.HttpSession;import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;@WebListener
public class SessionCount implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent se) {HttpSession session = se.getSession();ServletContext servletContext = session.getServletContext();Integer onlineCount = (Integer)servletContext.getAttribute("onlineCount");servletContext.setAttribute("onlineCount",++onlineCount);}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {HttpSession session = se.getSession();ServletContext servletContext = session.getServletContext();Integer onlineCount = (Integer)servletContext.getAttribute("onlineCount");servletContext.setAttribute("onlineCount",--onlineCount);}
}

查看人数的jsp

<%--Created by IntelliJ IDEA.User: 14408Date: 2023/2/17Time: 10:42To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>在线人数通知</title>
</head>
<body>
目前在线人数是${applicationScope.onlineCount}
</body>
</html>

退出的jsp

<%--Created by IntelliJ IDEA.User: 14408Date: 2023/2/17Time: 10:44To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%
request.getSession().invalidate();
%>
目前人数是${applicationScope.onlineCount}
</body>
</html>

3.2.3 ServletRquestListener

  • 监听域对象request。
  • 例如:监听接口的访问量:
    设置全局变量
servletContext.setAttribute("requestCount",0);

监听类

package net.lizheng.web.Listener.Ruquest;import javax.servlet.ServletContext;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;@WebListener
public class RequestCount implements ServletRequestListener {@Overridepublic void requestInitialized(ServletRequestEvent sre) {ServletContext servletContext = sre.getServletContext();Integer requestCount = (Integer)servletContext.getAttribute("requestCount");servletContext.setAttribute("requestCount",++requestCount);}@Overridepublic void requestDestroyed(ServletRequestEvent sre) {System.out.println("requestDestroyed");}
}

查看通知量的jsp

<%--Created by IntelliJ IDEA.User: 14408Date: 2023/2/17Time: 11:35To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>请求量</title>
</head>
<body>
接口请求量统计${applicationScope.requestCount}</body>
</html>


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部