Java Web小结

一、HTTP

概念:超文本传输协议,是一个简单的请求响应协议,通常运行在TCP之上。

  • 超文本指的是图片,音乐,视频,定位,地图等等…
  • HTTP是一种更为安全的协议,其基于HTTP协议,通过SSL或TLS提供加密处理数据、验证对方身份以及数据完整性。
  • HTTP端口号为80,HTTPS为443

消息请求和响应

以百度搜索为例

请求行

  • 请求地址
  • 请求方式
  • 状态码
  • 远程地址
    在这里插入图片描述
    请求消息头:(Request Headers)
  • 所支持的数据类型
  • 支持的编码格式
  • 语言环境
  • 缓存控制
  • 连接状态
  • Cookies信息
  • 主机名
    在这里插入图片描述
    响应消息头:(Response Headers)
  • Connection:处理完这次请求后,是断开连接还是继续保持连接
  • Content-Encoding:服务器通过这个头告诉浏览器数据的压缩格式
  • Content-Length:服务器通过这个头告诉浏览器回送数据的长度
  • Content-Type:服务器通过这个头告诉浏览器回送数据的类型
  • Date:当前时间值
  • Server:服务器通过这个头告诉浏览器服务器的类型
  • Vary:Accept-Encoding ——明确告知缓存服务器按照 Accept-Encoding 字段的内容,分别缓存不同的版本;
  • X-Powered-By:服务器告知客户机网站是用何种语言或框架编写的。

在这里插入图片描述

状态码

  • 200:请求响应成功 200
  • 3xx:请求重定向
  • 4xx:找不到资源 404 ,资源不存在;
  • 5xx:服务器代码错误 500 502:网关错误

待补充
1、面试题:浏览器中地址栏输入地址并回车的一瞬间到页面展示经历了什么步骤?
2、TCP/IP协议

二、Servlet

概念:Servlet是一种动态web技术,Java提供了一个Servlet接口,一个Servlet程序需要实现Servlet接口,并将该类部署到web服务器中。
Servlet的生命周期
1.加载servlet
2.创建servlet对象(调用构造器)
3.初始化

  • 调用此对象的init方法)(请求第一次到达时
  • 配置启动优先级可以让servlet在服务器启动时就初始化,牺牲服务器启动时间换取第一次执行时间

4.浏览器发送请求时服务器调用service方法
5.服务器停止时servlet销毁

servlet是单例的(只有一个实例)

1、HTTPServlet

Java中默认有有两个Servlet的实现类:HttpServlet,GenericServlet,其中后者是一个抽象类,只有一个唯一的抽象方法service,三者的继承关系如下:
在这里插入图片描述
HTTPServlet实现了service方法

abstract class HttpServlet extends GenericServlet{
 
   //HttpServlet中的service()
   protected void service(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse){
        //该方法通过httpServletRequest.getMethod()判断请求类型调用doGet() doPost()
   }
 
   //必须实现父类的service()方法
   public void service(ServletRequest servletRequest,ServletResponse servletResponse){
      HttpServletRequest request;
      HttpServletResponse response;
      try{
         request=(HttpServletRequest)servletRequest;
         response=(HttpServletResponse)servletResponse;
      }catch(ClassCastException){
         throw new ServletException("non-http request or response");
      }
      //调用service()方法
      this.service(request,response);
   }
}

从上面也可以看出,HTTPServlet依赖于两个接口:HttpServletRequest和HttpServletResponse,这两个接口继承了ServletRequest和ServletRespond接口,简单来说,这些接口提供了操作消息请求和响应的一系列方法(如下图所示)。
在这里插入图片描述

在这里插入图片描述
同时,Servlet类对客户端的请求响应处理是通过service方法实现的,而service方法最终调用了doGet和doPost两个方法。因此,在编写Servlet类时,我们只需要继承 HttpServlet,然后重写 doPost() 或者 doGet() 方法处理请求即可。
例如:

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().removeAttribute(Constants.USERSESSION);
        resp.sendRedirect("/login.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

Servlet的服务流程如下:

  • 浏览器向web服务器发送http(s)请求
  • web服务
  • 当客户端第一次访问该servlet时,服务器创建这个servlet实例对象;
  • 紧接着调用servlet的init方法完成这个servlet对象的初始化;
  • 服务器创建代表请求的request对象,和代表响应的response对象,调用servlet的service方法,响应客户端请求;
  • service方法执行(实际上是由用户重写的doGet和doPost方法进行响应处理),向代表响应的response对象中写入将要回送给浏览器的数据。
  • 服务器从response对象中取出相应的数据,构建一个http响应,回写给客户机浏览器。
  • 浏览器接受响应数据,解析数据进行显示。
    在这里插入图片描述

注册映射

实现的Servlet类一定要注册到web.xml下,并设置相应的映射路径,才能发挥作用。格式如下:

<!--注册Servlet--> 
<servlet> 
	<servlet-name>hello</servlet-name> 
	<servlet-class>com.lee.servlet.HelloServlet</servlet-class> 
</servlet> 
<!--Servlet的请求路径-->
<servlet-mapping>
	<servlet-name>hello</servlet-name>
	<!--前端可通过该请求路径访问到Servlet-->
	<url-pattern>/hello</url-pattern>
</servlet-mapping>

一个Servlet可以指定多个映射路径

2、ServletContext

概念:Web容器在启动的时候,会为每个web程序创建一个对应的ServletContext对象,它代表的当前的web应用。

1. 共享数据

由ServletContext的概念可以看出,一个web程序对应一个ServletContext对象,因此该对象对所有Servlet都是可见的,里面存放的数据可以被共享。
例如:

//LogoutServlet.class
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	//在ServletContext中存放属性值为Lee的username属性数据
        ServletContext context = this.getServletContext();
        String username = "lee";
        context.setAttribute("username", username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

//LoginServlet.class
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	//获取ServletContext中username属性的值
    	ServletContext context = this.getServletContext();
        String username = (String)req.getAttribute(Constants.USERSESSION);
        resp.setContentType("text/html"); 
        resp.setCharacterEncoding("utf-8"); 
        resp.getWriter().print("名字"+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3、获取初始化参数

ServletContext中可以设置一些初始化参数,在Servlet程序执行时可以通过getInitParameter()方法获取这些参数的值。通过在web.xml中添加标签实现,例如:

<context-param> 
	<param-name>initParam</param-name> 
	<param-value>hello</param-value> 
</context-param>

3、请求转发

通过ServletContext也可以实现请求的转发(通过request参数也可以实现),后面会详细讨论。

4、读取资源文件

ServletContext对象提供了一个getResourceAsStream(url)方法,可以将资源文件转化成流对象。用法如下:

//TestServlet.class
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	//通过ServletContext对象获取属性文件的流对象
    	InputStream is = this.getServletContext().getResourceAsStream("/WEB- INF/classes/com/lee/servlet/test.properties");
    	//将流对象转化成属性对象
    	Properties prop = new Properties();
    	prop.load(is);
    	//获取属性username
    	String username = prop.getProperty("username");
        resp.setContentType("text/html"); 
        resp.setCharacterEncoding("utf-8"); 
        //输出给浏览器
        resp.getWriter().print("名字"+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

ServletContext可用于统计网站在线人数、访问人次等

三、HTTPServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

1、类结构分析

向浏览器发送消息的方法
(继承的父类方法)
在这里插入图片描述

向浏览器发送响应头的方法
在这里插入图片描述
在这里插入图片描述
响应的状态码

  • 200:请求响应成功 200
  • 3xx:请求重定向
  • 4xx:找不到资源 404 ,资源不存在;
  • 5xx:服务器代码错误 500 502:网关错误

2、常见功能实现

文件下载

package com.lee.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;

public class FileDownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 获取要下载的文件路径
        String realPath = request.getParameter("downloadfile");
        //2. 获取下载的文件名
        if(realPath == null || realPath.length() == 0){
            //此处可以在前台进行处理
            realPath = "";
        }
        String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
        // 3.设置浏览器能支持下载
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
        // 4.获取文件的输入流
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(realPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("没有该文件!");
            response.sendRedirect("error.jsp");
            return;
        }

        // 5.创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        // 6.获取OutputStream对象
        ServletOutputStream out = response.getOutputStream();
        // 7.将FIleOutputStream流写入到缓冲区,使用OutputStream将缓冲区中的数据输出
        while((len = fis.read(buffer)) > 0){
            out.write(buffer, 0, len);
        }

        fis.close();
        out.close();
    }

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

上述为部分代码,完整代码详见github

随机验证码生成

package com.lee.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class ImagServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //浏览器自动刷新:3秒per
        resp.setHeader("refresh", "3");
        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        //得到图片进行操作
        Graphics2D g = (Graphics2D) image.getGraphics();
        //设置背景
        g.setColor(Color.white);
        g.fillRect(0, 0, 80,20);
        //给图片写数据
        g.setColor(Color.BLACK);
        g.setFont(new Font(null, Font.BOLD, 20));
        g.drawString(makeNum(), 0, 20);

        //告诉浏览器以图片形式打开
        resp.setContentType("image/jpeg");
        //不让浏览器缓存
        resp.setDateHeader("expires", -1);
        resp.setHeader("Cache-Control", "no-cache");
        resp.setHeader("Pragma", "no-cache");
        //把图片写给浏览器
        ImageIO.write(image, "jpg", resp.getOutputStream());
    }

    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 6 - num.length(); i++) {
            sb.append("0");
        }
        return sb.toString() + num;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3、重定向

概念:当web服务端获取到客户端的请求后,可以通过HttpServletResponse的sendRedirect(url)方法实现请求的重定向,简单来说就是再次通知客户端区访问另一个资源(我处理不了(完毕),去找别人)。

应用场景:用户成功登录后,将请求重定向到主页。

@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //处理请求 
	String username = req.getParameter("username"); 
	String password = req.getParameter("password"); 
	System.out.println(username+":"+password); 
	
	/*调用判断登录信息的业务代码*/
	
	//重定向时候注意路径问题 
	resp.sendRedirect("/r/success.jsp");
}

四、HTTPServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;

HttpServletRequest主要用于获取客户端的请求参数,因此提供了大量的方法供开发者调用。

  • 获取属性值
  • 获取参数值(属性和参数实际上只是一个参量的两种不同表现形式)
  • 获取session
  • 获取方法名

    在这里插入图片描述
    在这里插入图片描述

请求转发

概念:请求转发是指将请求再转发到另一资源(一般为JSP或Servlet)。此过程依然在同一个请求范围内,转发后浏览器地址栏内容不变。
应用场景:当用户登录信息输入错误,将请求转发到当前页,输出错误信息。

//对应login.jsp
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("loginServlet...start...");
        String userCode = req.getParameter("userCode");
        String userPassword = req.getParameter("userPassword");

		//调用业务层代码,获取用户对应的数据对象
        UserServiceImpl userService = new UserServiceImpl();
        User user = userService.userLogin(userCode, userPassword);

        if(user != null){//成功查找到用户,重定向至主页
            req.getSession().setAttribute(Constants.USERSESSION, user);
            resp.sendRedirect("/jsp/frame.jsp");
        }else{//数据库中不存在该用户,设置错误属性值,将请求重新转发给当前页
            req.setAttribute("error", "用户名或密码不正确");
            req.getRequestDispatcher("login.jsp").forward(req, resp);
        }
    }

概念详解

  • getParameter()和getAttribute()方法的区别(参考资料
  • request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据,,request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段。
  • request.getParameter()方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。request.getParameter()方法返回String类型的数据。 request.setAttribute()和getAttribute()方法传递的数据只会存在于Web容器内部
  • HttpServletRequest类有setAttribute()方法,而没有setParameter()方法。
  • 重定向和转发的异同

相同点:页面都会实现跳转
不同点

  • forward()只能将请求转发给同一个Web应用中的组件,而sendRedirect()方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到其他站点的资源。
  • sendRedirect()方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变(302),由初始的URL地址变成重定向的目标URL;而调用forward()方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变(307)。
  • forward()方法的调用者与被调用者之间共享相同的request对象和response对象;而sendRedirect()方法调用者和被调用者使用各自的request对象和response对象,它们属于两个独立的请求和响应过程。

五、Cookie和Session

1、会话

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

抽象理解:会话是一种客户端访问服务端后证明自己已经访问过给服务端的技术理念。cookie类似于服务端给客户端的一个信物,客户端再次访问是只需要带上信物服务端就可以识别该客户端;而session类似于服务端为每个客户端进行一次信息登记,等客户端下次访问时服务端会进行查询匹配。

2、Cookie

类结构
在这里插入图片描述
Cookie包含几个关键属性,并设置了相应的getter,setter方法。

String name:该Cookie的名称。Cookie一旦创建,名称便不可更改
Object value:该Cookie的值。如果值为Unicode字符,需要为字符编码。如果值为二进制数据,则需要使用BASE64编码。
int maxAge:该Cookie失效的时间,单位秒。如果为正数,则该Cookie在maxAge秒之后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为–1。
boolean secure:该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。
String path:该Cookie的使用路径。如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie。如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/”
String domain:可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。
String comment:该Cookie的用处说明。浏览器显示Cookie信息的时候显示该说明
int version:该Cookie使用的版本号。0表示遵循Netscape的Cookie规范,1表示遵循W3C的RFC 2109规范。

要点

  • cookie一般会保存在本地的用户目录下 appdata;
  • 一个Cookie只能保存一个信息;
  • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
  • Cookie大小有限制4kb;
  • 浏览器上限一般为300个cookie
  • 在使用Unicode字符进行Cookie的属性设置时,需要进行解码和编码,采用以下方法实现
URLEncoder.encode("测试","UTF-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")

3、Session

  • 服务器会给每一个用户(浏览器)创建一个Seesion对象;
  • 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
  • 可用于保存用户的信息;保存购物车的信息等

类结构

类结构较为简单,如下
在这里插入图片描述
示例

public class SessionDemo01 extends HttpServlet {
	@Override 
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//解决乱码问题
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=utf-8");
		//得到Session 
		HttpSession session = req.getSession(); 
		//给Session中存东西 
		session.setAttribute("name",new Person("小王",1));
		//获取Session的ID 
		String sessionId = session.getId();

		//判断Session是不是新创建 
		if (session.isNew()){
			resp.getWriter().write("session创建成功,ID:"+sessionId); 
		}else {
			resp.getWriter().write("session以及在服务器中存在 了,ID:"+sessionId);
		}
		
		//Session创建的时候其实生成了一个Cookie; 见下面的注解
		// Cookie cookie = new Cookie("JSESSIONID",sessionId); 
		// resp.addCookie(cookie);
}

注:虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。
该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。
因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。

Session和cookie的区别参考地址

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
  • Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资
    源的浪费)
  • Session对象由服务器创建,该对象会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。如果对服务器性能方比较敏感,应当使用cookie。
  • Cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
  • 设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话(session同样可在web.xml中设置过期时间,见下)。
<!--设置Session默认的失效时间--> 
<session-config> 
	<!--15分钟后Session自动失效,以分钟为单位--> 
	<session-timeout>15</session-timeout> 
</session-config>

六、JSP

概念:Java Server Pages ,Java服务器端页面,也和Servlet一样,用于动态Web技术!

JSP可以视为是一种特殊的HTML;HTML只给用户提供静态的数据,而JSP页面中可以嵌入JAVA代码,为用户提供动态数据。

1、JSP原理

在服务器的内部,例如Tomcat中会存在一个work目录(或IDEA中使用的Tomcat的Tomcat目录下),可以看到所有的JSP最终也被转换成一个java类。
在这里插入图片描述
因此,JSP本质上其实就是一个Servlet,只不过进行了额外的包装。

在JSP页面中;只要是 JAVA代码就会原封不动的输出;如果是HTML代码,就会被转换为:out.write("<html>\r\n");格式,输出到前端。

2、JSP基础语法

JSP表达式<%= new java.util.Date()%>
JSP脚本片段:与java类似

<%
	int sum = 0; 
	for (int i = 1; i <=100 ; i++) { 
		sum+=i; 
	}
	out.println("<h1>Sum="+sum+"</h1>"); 
%>

JSP声明:与java类似

<%!
	static { 
		System.out.println("Loading Servlet!"); 
	}
	private int globalVar = 0; 
	public void kuang(){ 
		System.out.println("进入了方法Kuang!"); 
	} 
%>

3、JSP指令

<%@page args.... %> 
<%@include file=""%> 
<%--@include会将两个页面合二为一--%> 
<%@include file="common/header.jsp"%> 
<%@include file="common/footer.jsp"%> 
<%--jSP标签 jsp:include:拼接页面,本质还是三个 --%>

4、9大内置对象

  • PageContext (保存的数据只在一个页面中有效)
  • Request (保存的数据只在一次请求中有效)
  • Response(保存的数据只在一次请求中有效)
  • Session (保存的数据只在一次会话中有效)
  • Application 【SerlvetContext】 (保存的数据只在服务器中有效)
  • config 【SerlvetConfig】
  • out
  • page
  • exception

JSP标签、EL表达式、JSTL表达式:几乎不用(略)

七、MVC

Model-view-Controller: 模型-视图-控制器

在这里插入图片描述

Model

  • 业务处理 :业务逻辑(Service)
  • 数据持久层:CRUD (Dao)

View

  • 展示数据
  • 提供链接发起Servlet请求 (a,form,img…)

Controller (Servlet)

  • 接收用户的请求 :(req:请求参数、Session信息….)
  • 交给业务层处理对应的代码
  • 控制视图的跳转

八、过滤器

实现Filter接口,用来过滤网站的数据,例如处理中文乱码、登录验证、垃圾信息屏蔽等。

示例:处理乱码问题

public class CharacterEncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("CharacterEncodingFilter初始化...");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
		System.out.println("CharacterEncodingFilter销毁...");
    }
}

注册代码:

<filter>
   <filter-name>characterEncoding</filter-name>
   <filter-class>com.lee.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>characterEncoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在这里插入图片描述
在这里插入图片描述

从运行结果中,可以看出过滤器在服务器的启动时被创建,随时等待过滤对象的出现;而在服务器关闭前会被销毁。

九、监听器

监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。监听器在GUI编程中非常常见,HttpSessionListener是一个用来处理web事件的特殊监听器接口,开发者使用监听器时需要实现该接口,并重写sessionCreated和sessionDestroyed方法,以对客户端和服务端的连接进行监听。

示例:实现网站在线人数的监听

public class OnlineCountListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    	//客户端发出请求,session被创建时调用,即用户浏览网页,网站在线人数增加
        ServletContext sc = httpSessionEvent.getSession().getServletContext();
        System.out.println(httpSessionEvent.getSession().getId());
        Integer count = (Integer) sc.getAttribute("OnlineCount");

        if(count == null){
        	//首次被访问
            count = new Integer(1);
        }else {
            int i = count.intValue();
            count = new Integer(i+1);
        }
        System.out.println("count:" + count);
        sc.setAttribute("OnlineCount", count);
    }

    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
    	//session销毁时调用,即关闭浏览器时,网站在线人数减少
        ServletContext sc = httpSessionEvent.getSession().getServletContext();

        Integer count = (Integer) sc.getAttribute("OnlineCount");

        if(count == null){
            count = new Integer(0);
        }else {
            int i = count.intValue();
            count = new Integer(i-1);
        }

        sc.setAttribute("OnlineCount", count);
        httpSessionEvent.getSession().invalidate();
    }
}

注册代码:

<listener>
   <listener-class>com.lee.listener.OnlineCountListener</listener-class>
</listener>

扩展

web中常见的功能代码:

  • 文件上传
  • 邮件发送
  • 数据管理系统(CRUD)

小结

本篇文章讲解了Java Web的相关知识,其中最核心的概念就是Servlet,这是web开发的根本技术。为了简化代码的编写,提高开发效率,后面将进一步介绍相关的应用框架。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leo木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值