处理中文乱码,我们在之前需要每个类里面都需要写,要是有一个机制在每次调用Servlet之前就去把这个乱码处理好就很好。
登录验证。
Servlet要拿到一个Request和Response,就是因为web服务器要给他这两个对象。过滤器也需要这两个对象,才能进行处理。所以说过滤器和servlet一模一样。Servlet实现Servlet接口,过滤器实现过滤器接口。
我们在pom.xml进行配置如下所示:
-
-
-
javax.servlet.jsp -
javax.servlet.jsp-api -
2.3.3 -
provided -
-
-
-
javax.servlet -
javax.servlet-api -
4.0.1 -
provided -
-
-
-
-
javax.servlet.jsp.jstl -
jstl-api -
1.2 -
-
-
-
-
taglibs -
standard -
1.1.2 -
-
-
-
mysql -
mysql-connector-java -
8.0.27 -
(1)导包不要错:
我们所导入的包为javax.servlet的Filter
之后进入之后:
点击implement methods,进行重写方法:
之后我们可以先体现一个乱码的形式,从而去体现过滤器的作用:
我们创建servlet包下的ShowServlet类,我们的代码如下所示:
- package com.rgf.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 ShowServlet extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- resp.getWriter().write("你好,加油");
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- doGet(req, resp);
- }
- }
之后我们你在web.xml里面进行注册:
- "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_3_1.xsd"
- version="3.1"
- metadata-complete="true">
- <servlet>
- <servlet-name>ShowServletservlet-name>
- <servlet-class>com.rgf.servlet.ShowServletservlet-class>
- servlet>
- <servlet-mapping>
- <servlet-name>ShowServletservlet-name>
- <url-pattern>/servlet/showurl-pattern>
- servlet-mapping>
-
- web-app>
我们进行运行后如下所示:
我们发现出现了中文乱码。
我们在之前的解决方法是在输出之前加入如下代码:
resp.setContentType("text/html;charset=utf-16");
我们还可以在一个项目里面写两个运行名字:
-
ShowServlet -
com.rgf.servlet.ShowServlet -
-
ShowServlet -
/servlet/show -
-
-
ShowServlet -
/show -
重新运行之后如下所示:
我们发现成功转变成为了中文。
之后,我们利用Filter进行查看:我们将在ShowServlet类中的解决乱码问题的代码:
resp.setContentType("text/html;charset=utf-16");
进行注释掉,或者删掉。
我们创建新的包filter,创建新的类:ShowServlet。
按照如上方法进行创建方法。之后我们进行编写代码:
(2)实现Filter接口,重写对应的方法即可。
- package com.rgf.filter;
-
- import javax.servlet.*;
- import java.io.IOException;
-
- public class CharacterEncodingFilter implements Filter{
-
- //初始化:web服务器启动,就已经初始化了。随时等待过滤对象出现!
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.out.println("CharacterEncodingFilter初始化");
- }
-
- @Override
- //filterChain:链,可以有很多个过滤器.我们需要通过filterChain来放行对象
- /*
- 1.过滤中的所有代码,在过滤特定请求的时候,都会执行
- 2.必须要让过滤器继续通行Chain.doFilter(request,response)l,就需要把这个请求往下转交
- */
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain Chain) throws IOException, ServletException {
- request.setCharacterEncoding("utf-8");
- response.setCharacterEncoding("utf-8");
- response.setContentType("text/html;charset=utf-8");
- System.out.println("CharacterEncodingFilter执行前..");
- //以下代码起到放行的作用,否则过滤器到这里就停下来了。我们需要通过filterChain来放行对象
- //其中doFilter,我们按住ctrl键进入源码界面,我们会发现他的两个参数为request和response。
- Chain.doFilter(request,response);//让我们的请求继续走,如果不写,程序到这里就拦截停止了。
- System.out.println("CharacterEncodingFilter执行后..");
- }
- //销毁 :web服务器关闭的时候,过滤会销毁
- @Override
- public void destroy() {
- System.out.println("CharacterEncodingFilter销毁");
- }
- }
如下所示:
当前有两个过滤器的时候,我们都需要拿到response和request。
通过 Chain.doFilter(request,response);//让我们的请求继续走,如果不写,程序到这里就拦截停止了。这个代码进行交接。
我们完成代码的编写之后,我们进行在web.xml里面进行配置如下所示:
-
CharacterEncodingFilter -
com.rgf.filter.CharacterEncodingFilter -
-
-
CharacterEncodingFilter -
-
/servlet/* -
我们在编写上一个类的时候,我们在web.xml里面对于一个请求可以通过两个访问,而我们的过滤器实现功能是在第一个请求里面就。(/servlet/show)
-
ShowServlet -
com.rgf.servlet.ShowServlet -
-
ShowServlet -
/servlet/show -
-
-
ShowServlet -
/show -
运行之后,我们如下所示:
之后我们访问的地址为:http://localhost:9571/javaweb_filter01_war_exploded/servlet/show
访问之后如下所示:
我们进行查看如下所示:
我们发现这个类进行初始化,web服务器启动的时候,就已经初始化了,随时等待过滤对象出现。
我们来看过滤器什么时候进行销毁:
我们访问这个之后我们发现出现乱码,之后再访问/servlet/show,如下所示:
我们停止服务器之后如下所示:
我们发现过滤器进行了销毁。
我们查看初始化的时候,我们发现如下所示:
我们发现可以获取初始化的参数,获取上下文的对象。我们可以再服务器已启动的时候设置一些固有的东西进去,让所有人都可以访问。当然很少这样子做。
我们打开这个浏览器,没有任何问题,浏览器是一个客户端软件,关闭的时候点一下关闭即可关闭。我们点击关闭的时候:点一下它,它受到一个点击事件,收到点击事件之后执行一个动作,把浏览器进程给截了并且关闭窗口。
实现一个监听器的接口:(有N种)
我们进行运行之后如下所示:
但是我们所设计的代码里面只有一个人,为什么会 有两个人在线。我们进行如下所示:
- package com.rgf.listener;
-
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpSessionEvent;
- import javax.servlet.http.HttpSessionListener;
-
- //统计网站在线人数:统计session
- public class OnlineCountListener implements HttpSessionListener {
- @Override
- //创建session的监听:看你的一举一动
- //一旦创建session就会触发一次这个事件。
- public void sessionCreated(HttpSessionEvent se) {
- /*我们监听器假设session创建的话,我们要获取OnlineCount对象,如果OnlineCount对象为空,我们要给他赋一个值,让他为1.
- 如果不为空,则每一次都会加1。每一次都会更新onlineCount.
- */
- //HttpSessionEvent代表session事件的一个对象
- //通过getSession拿到session,拿到session之后我们就可以拿到网站的上下文,通过getServletContext
- //我们统计在线人数,是统计所有网站,所有人都可以访问到它,我们要把它提高到最高的作用域:ServletContext或者application
- ServletContext ctx = se.getSession().getServletContext();
- System.out.println(se.getSession().getId());
- //有了这个对象之后,我们就可以存东西了(setAttribute)我们先进行取(getAttribute),判断没有在进行存。
- //我们先取一个OnlineCount东西。强转为整型数据(int)
- Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
-
- if(onlineCount==null){
- //网站一个人都没有,我们进行+1.
- onlineCount=new Integer(1);
- }else {
- //将数量的类型count转换为int。
- int count=onlineCount.intValue();
-
- onlineCount=new Integer(count+1);
- }
-
- ctx.setAttribute("OnlineCount",onlineCount);
- }
-
- @Override
- //销毁session监听
- //一旦销毁session就会触发一次这个事件。
- public void sessionDestroyed(HttpSessionEvent se) {
- ServletContext ctx = se.getSession().getServletContext();
- //有了这个对象之后,我们就可以存东西了(setAttribute)我们先进行取(getAttribute),判断没有在进行存。
- //我们先取一个OnlineCount东西。强转为整型数据(int)
- Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
-
- if(onlineCount==null){
- //网站一个人都没有,我们记为0.
- onlineCount=new Integer(0);
- }else {
- //将数量的类型count转换为int。
- int count=onlineCount.intValue();
-
- onlineCount=new Integer(count-1);
- }
-
- ctx.setAttribute("OnlineCount",onlineCount);
- }
-
- }
我们增加
System.out.println(se.getSession().getId());
从而获取他们的ID号。
运行之后我们发现如下所示:
我们发现有两个ID,输出了两个sessionID,可我们只有一个,另外一个是怎么来的呢:
启动浏览器的时候就在进行连接,有可能连接失败,但是session已经存在了,直到连接成功的时候就成为了2次。
我们发现最后一次输出的ID与该session相同。而第一个已经销毁了。
我们来重新发布一下项目:
重新运行之后看是否为一个,如下所示:
我们可以试试用同一浏览器和不同浏览器进行查看:
我们都在谷歌浏览器进行访问的时候,如下所示:
我们发现session是一样的。
我们使用双核浏览器进行访问:
我们发现两个不同的浏览器才是不一样的客户端。
- package com.rgf.listener;
-
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpSessionEvent;
- import javax.servlet.http.HttpSessionListener;
-
- //统计网站在线人数:统计session
- public class OnlineCountListener implements HttpSessionListener {
- @Override
- //创建session的监听:看你的一举一动
- //一旦创建session就会触发一次这个事件。
- public void sessionCreated(HttpSessionEvent se) {
- /*我们监听器假设session创建的话,我们要获取OnlineCount对象,如果OnlineCount对象为空,我们要给他赋一个值,让他为1.
- 如果不为空,则每一次都会加1。每一次都会更新onlineCount.
- */
- //HttpSessionEvent代表session事件的一个对象
- //通过getSession拿到session,拿到session之后我们就可以拿到网站的上下文,通过getServletContext
- //我们统计在线人数,是统计所有网站,所有人都可以访问到它,我们要把它提高到最高的作用域:ServletContext或者application
- ServletContext ctx = se.getSession().getServletContext();
- System.out.println(se.getSession().getId());
- //有了这个对象之后,我们就可以存东西了(setAttribute)我们先进行取(getAttribute),判断没有在进行存。
- //我们先取一个OnlineCount东西。强转为整型数据(int)
- Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
-
- if(onlineCount==null){
- //网站一个人都没有,我们进行+1.
- onlineCount=new Integer(1);
- }else {
- //将数量的类型count转换为int。
- int count=onlineCount.intValue();
-
- onlineCount=new Integer(count+1);
- }
-
- ctx.setAttribute("OnlineCount",onlineCount);
- }
-
- @Override
- //销毁session监听
- //一旦销毁session就会触发一次这个事件。
- public void sessionDestroyed(HttpSessionEvent se) {
- ServletContext ctx = se.getSession().getServletContext();
- //有了这个对象之后,我们就可以存东西了(setAttribute)我们先进行取(getAttribute),判断没有在进行存。
- //我们先取一个OnlineCount东西。强转为整型数据(int)
- Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
-
- if(onlineCount==null){
- //网站一个人都没有,我们记为0.
- onlineCount=new Integer(0);
- }else {
- //将数量的类型count转换为int。
- int count=onlineCount.intValue();
-
- onlineCount=new Integer(count-1);
- }
-
- ctx.setAttribute("OnlineCount",onlineCount);
- }
- /*
- session销毁的两种情况
- 1.手动销毁 se.getSession.invalidate;
- 52.自动销毁 在web.xml里面配置session过期时间。:
-
1 -
- */
- }
-
-
-
com.rgf.listener.OnlineCountListener -
4.看情况是否使用。