• JavaWeb开发之Servlet&Request&Response


    Servlet其实就一个运行在web服务器上的小的Java程序,用于处理从web客户端发送的请求,并且对请求作出响应。使用Servlet需要编写一个Java类实现Servlet的接口,并配置Servlet。Servlet是在第一次被访问的时候会被实例化,只要Servlet一被实例化那么Servlet中的init方法就会执行(init只会执行一次)。任何一次从客户端发送来的请求,那么Servlet中的service方法就会执行(在service方法的内部根据请求的方式不同调用不同doXXX方法)。当Servlet从服务器中移除或者服务器关闭的时候Servlet对象被销毁,里面的destroy方法就会执行,然后垃圾回收就会将其回收掉。

    目录

    一、servlet对象

    1、Servlet入门程序

    2、servlet的实现关系

    3、Servlet的生命周期

    4、ServletConfig对象

    5、ServletContext对象

    二、Response对象

    1、response对象的常用API

     2、response对象响应中文乱码问题

     三、Request对象

    1、request对象常用的API

     2、request对象的常用API代码演示

    3、request对象接收表单请求参数

    4、Request对象接收表单请求参数的中文乱码处理


    一、servlet对象

    1、Servlet入门程序

    创建web项目,配置tomcat服务器,首先创建一个类,并实现Servlet接口,如下:

    1. import javax.servlet.*;
    2. import java.io.IOException;
    3. public class HelloServlet implements Servlet {
    4. @Override
    5. public void init(ServletConfig servletConfig) throws ServletException {
    6. }
    7. @Override
    8. public ServletConfig getServletConfig() {
    9. return null;
    10. }
    11. @Override
    12. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    13. servletResponse.getWriter().println("HelloServlet");
    14. }
    15. @Override
    16. public String getServletInfo() {
    17. return null;
    18. }
    19. @Override
    20. public void destroy() {
    21. }
    22. }

    在web.xml配置servlet的名称和路径等,具体如下:

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>HelloServletservlet-name>
    8. <servlet-class>servlet.HelloServletservlet-class>
    9. servlet>
    10. <servlet-mapping>
    11. <servlet-name>HelloServletservlet-name>
    12. <url-pattern>/HelloServleturl-pattern>
    13. servlet-mapping>
    14. web-app>

    2、servlet的实现关系

    Servlet接口,GenericServlet类是通用的Servlet,是一个与协议无关的Servlet,HttpServlet类是Http专用的Servlet。SUN设计之初,是有想法的,以后的互联网不仅仅只使用http协议,可以通过GenericServlet实现。HttpServlet是一个与协议相关的Servlet是专门用来处理HTTP协议的请求。通常编写一个Servlet一般都会让这个Servlet继承HttpServlet重写service方法。在service方法内部根据请求方式不同执行不同的doXXX的方法(get请求执行doGet方法,如果是post请求就会执行doPost方法)。所以往往继承了HttpServlet之后不需要重写service方法,只需要重写doGet和doPost方法即可。往往请求要处理的内容的代码都是一致的,所以需要让doGet和doPost相互调用可以简化编程。

    3、Servlet的生命周期

    Servlet生命周期:Servlet对象从创建到销毁的过程。

    1. Servlet何时被创建又是何时被销毁的?

    Servlet中有init,service,destroy方法,这几个方法称为是Servlet生命周期相关的方法。

    1. Servlet是在第一次被访问的时候会被实例化,只要Servlet一被实例化那么Servlet中的init方法就会执行(init只会执行一次)。任何一次从客户端发送来的请求,那么Servlet中的service方法就会执行(在service方法的内部根据请求的方式不同调用不同doXXX方法)。当Servlet从服务器中移除或者服务器关闭的时候Servlet对象被销毁,里面的destroy方法就会执行,然后垃圾回收就会将其回收掉。
    1. import javax.servlet.*;
    2. import java.io.IOException;
    3. public class HelloServlet implements Servlet {
    4. @Override
    5. public void init(ServletConfig servletConfig) throws ServletException {
    6. System.out.println("servlet被初始化了");
    7. }
    8. @Override
    9. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    10. System.out.println("Servlet被执行了");
    11. }
    12. @Override
    13. public void destroy() {
    14. System.out.println("servlet被销毁了");
    15. }
    16. @Override
    17. public ServletConfig getServletConfig() {
    18. return null;
    19. }
    20. @Override
    21. public String getServletInfo() {
    22. return null;
    23. }
    24. }

    4、ServletConfig对象

    ServletConfig用来获得Servlet的相关的配置的对象。它的常用API如下,其中第一个方法用于获得Servlet的初始化参数,第二个方法用于获得ServletContext对象,第三个方法用于获得Servlet名称。 

    下面演示一下使用ServletConfig 的API,首先在web.xml中配置初始化参数,servlet名称等,具体如下:

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>ServletDemo01servlet-name>
    8. <servlet-class>servlet.ServletDemo01servlet-class>
    9. <init-param>
    10. <param-name>usernameparam-name>
    11. <param-value>rootparam-value>
    12. init-param>
    13. <init-param>
    14. <param-name>passwordparam-name>
    15. <param-value>123456param-value>
    16. init-param>
    17. servlet>
    18. <servlet-mapping>
    19. <servlet-name>ServletDemo01servlet-name>
    20. <url-pattern>/ServletDemo01url-pattern>
    21. servlet-mapping>
    22. web-app>

    在Servlet中使用ServletConfig的API获得响应参数,具体如下:

    1. import javax.servlet.ServletConfig;
    2. import javax.servlet.ServletException;
    3. import javax.servlet.annotation.WebServlet;
    4. import javax.servlet.http.HttpServlet;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import java.io.IOException;
    8. import java.util.Enumeration;
    9. @WebServlet(name = "ServletDemo01")
    10. public class ServletDemo01 extends HttpServlet {
    11. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    12. doGet(request, response);
    13. }
    14. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15. //获得初始化参数
    16. ServletConfig config = this.getServletConfig();
    17. String username = config.getInitParameter("username");
    18. String password = config.getInitParameter("password");
    19. System.out.println(username + " " + password);
    20. //获得所有初始化参数名称
    21. Enumeration names = config.getInitParameterNames();
    22. while (names.hasMoreElements()){
    23. String name = names.nextElement() ;
    24. String value = config.getInitParameter(name) ;
    25. System.out.println(name + " " + value);
    26. }
    27. //获得Servlet名称
    28. String name = config.getServletName() ;
    29. System.out.println(name);
    30. }
    31. }

    5、ServletContext对象

    ServletContext:Servlet的上下文对象。ServletContext对象对Servlet之前和之后的内容都知道。这个对象一个web项目只有一个。在服务器启动的时候为每个web项目创建一个单独的ServletContext对象。

    该对象的常用API如下:分别为获取文件的MIME类型 ,获取Web项目请求路径的工程名,获得web项目的初始化参数。

     配置web.xml

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <context-param>
    7. <param-name>usernameparam-name>
    8. <param-value>rootparam-value>
    9. context-param>
    10. <context-param>
    11. <param-name>passwordparam-name>
    12. <param-value>123456param-value>
    13. context-param>
    14. <servlet>
    15. <servlet-name>ServletDemo02servlet-name>
    16. <servlet-class>servlet.ServletDemo02servlet-class>
    17. servlet>
    18. <servlet-mapping>
    19. <servlet-name>ServletDemo02servlet-name>
    20. <url-pattern>/ServletDemo02url-pattern>
    21. servlet-mapping>
    22. web-app>

    测试了ServletContext对象的几个API:

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. import java.util.Enumeration;
    8. @WebServlet(name = "ServletDemo02")
    9. public class ServletDemo02 extends HttpServlet {
    10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    11. doGet(request,response);
    12. }
    13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. //获得请求路径的工程名
    15. String path = request.getServletContext().getContextPath() ;
    16. System.out.println(path);
    17. //获得全局初始化参数
    18. String username = request.getServletContext().getInitParameter("username") ;
    19. String password = request.getServletContext().getInitParameter("password") ;
    20. System.out.println(username + " " + password);
    21. Enumeration names = request.getServletContext().getInitParameterNames();
    22. while (names.hasMoreElements()){
    23. String name = names.nextElement() ;
    24. String value = request.getServletContext().getInitParameter(name) ;
    25. System.out.println(name + " " + value);
    26. }
    27. }
    28. }

    之前使用IO流就可以读取文件(java项目中)。现在是一个web项目,web项目需要发布到tomcat下才能访问的。获取web项目下的文件如果使用传统的IO就会出现问题(原因:路径中使用的是相对路径,相对的是JRE环境)。这里我们使用ServletContext对象读取web工程下的文件。

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.FileInputStream;
    7. import java.io.IOException;
    8. import java.io.InputStream;
    9. import java.util.Enumeration;
    10. import java.util.Properties;
    11. @WebServlet(name = "ServletDemo02")
    12. public class ServletDemo02 extends HttpServlet {
    13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. doGet(request,response);
    15. }
    16. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. Properties properties = new Properties() ;
    18. String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties") ;
    19. System.out.println(path);
    20. InputStream is = new FileInputStream(path) ;
    21. properties.load(is);
    22. String driveClassName = properties.getProperty("driverClassName") ;
    23. String username = properties.getProperty("username") ;
    24. String password = properties.getProperty("password") ;
    25. String url = properties.getProperty("url") ;
    26. System.out.println(driveClassName);
    27. System.out.println(url);
    28. System.out.println(username);
    29. System.out.println(password);
    30. }
    31. }

    域对象:指的是将数据存入到域对象中,这个数据就会有一定的作用范围。域指的是一定的作用范围。ServletContext是在服务器启动的时候为每个web项目单独创建一个ServletContext对象。当web项目从服务器中移除,或者是关闭服务器的时候ServletContext对象会被销毁。向ServletContext中保存的数据一直存在(当服务器关闭的时候ServletContext对象被销毁,然后里面数据才会失效)。范围:整个web应用。ServletContext作为域对象的常用API如下所示:

    1. 存入数据的方法:

    1. 获取数据的方法:

    1. 移除数据的方法:

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.FileInputStream;
    7. import java.io.IOException;
    8. import java.io.InputStream;
    9. import java.util.Enumeration;
    10. import java.util.Properties;
    11. @WebServlet(name = "ServletDemo02")
    12. public class ServletDemo02 extends HttpServlet {
    13. @Override
    14. public void init() throws ServletException {
    15. this.getServletContext().setAttribute("name","张三");
    16. }
    17. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    18. doGet(request,response);
    19. }
    20. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    21. String name = (String) this.getServletContext().getAttribute("name");
    22. System.out.println(name);
    23. }
    24. }

    二、Response对象

    1、response对象的常用API

    开发的软件是B/S结构的软件,可以通过浏览器访问服务器的软件。从浏览器输入一个地址访问服务器(将这个过程称为是请求)。服务器接收到请求request,需要进行处理,处理以后需要将处理结果显示回浏览器端(将这个过程称为是响应response)。

    设置状态码的方法:

     设置响应头的方法

     关于响应体的方法:

    重定向的方法:

     设置浏览器打开页面时候采用的字符集:

    设置字符流响应的缓冲的字符集:
     服务器向浏览器回写cookie的方法:

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.FileInputStream;
    7. import java.io.IOException;
    8. import java.io.InputStream;
    9. import java.util.Enumeration;
    10. import java.util.Properties;
    11. @WebServlet(name = "ServletDemo02")
    12. public class ServletDemo02 extends HttpServlet {
    13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. doGet(request,response);
    15. }
    16. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. response.setStatus(404); //设置响应的状态码
    18. response.setHeader("Location","/servlet_war_exploded/servlet/ServletDemo01");
    19. //设置响应后的浏览器编码
    20. response.setContentType("text/html;charset=utf-8");
    21. //定时刷新
    22. response.getWriter().println("5s后跳转");
    23. response.setHeader("Refresh","5;url=/servlet_war_exploded/ServletDemo02");
    24. }
    25. }

     2、response对象响应中文乱码问题

     对于使用字节流响应中文,需要设置浏览器打开时默认字符集和中文翻译成字节数组时的编码方式保持一致即可,具体如下:

     对于响应字符流,获得字符流缓冲区的编码和设置浏览器默认打开时候采用的字符集一致即可。

     三、Request对象

    开发的软件都是B/S结构软件,从浏览器向服务器提交一些数据,将这些内容进行封装就封装成了一个请求对象(Request对象)。

    1、request对象常用的API

     2、request对象的常用API代码演示

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.FileInputStream;
    7. import java.io.IOException;
    8. import java.io.InputStream;
    9. import java.util.Enumeration;
    10. import java.util.Properties;
    11. @WebServlet(name = "ServletDemo02")
    12. public class ServletDemo02 extends HttpServlet {
    13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. doGet(request,response);
    15. }
    16. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. System.out.println("请求方式:" + request.getMethod());
    18. System.out.println("客户机IP地址:" + request.getRemoteAddr());
    19. System.out.println("请求参数的字符串:" + request.getQueryString());
    20. System.out.println("请求路径的URL:" + request.getRequestURL());
    21. System.out.println("请求路径的URI:" + request.getRequestURI());
    22. System.out.println("客户机浏览器的类型:"+request.getHeader("User-Agent"));
    23. }
    24. }

    3、request对象接收表单请求参数

    创建一个html页面,用于提交表单,如下所示,提交到servlet:

    1. html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Insert title heretitle>
    6. head>
    7. <body>
    8. <h1>request接收表单参数h1>
    9. <form action="/servlet_war_exploded/RequestDemo02" method="post">
    10. 用户名:<input type="text" name="username"/><br/>
    11. 密码:<input type="password" name="password"><br/>
    12. 性别:<input type="radio" name="sex" value="man"/><input type="radio" name="sex" value="woman"/><br/>
    13. 籍贯:<select name="city">
    14. <option value="beijing">北京市option>
    15. <option value="shanghai">上海市option>
    16. <option value="shenzhen">深圳市option>
    17. select><br/>
    18. 爱好:<input type="checkbox" name="hobby" value="basketball"/>篮球
    19. <input type="checkbox" name="hobby" value="football"/>足球
    20. <input type="checkbox" name="hobby" value="volleyball"/>排球<br/>
    21. 自我介绍:<textarea name="info" rows="3" cols="8">textarea><br/>
    22. <input type="submit" value="提交">
    23. form>
    24. body>
    25. html>

    在servlet中接收表单的参数信息并打印,具体如下:

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. import java.util.Arrays;
    8. import java.util.Map;
    9. @WebServlet(name = "RequestDemo02")
    10. public class RequestDemo02 extends HttpServlet {
    11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    12. // 接收用户名和密码:
    13. String username = request.getParameter("username");
    14. String password = request.getParameter("password");
    15. // 接收性别和籍贯:
    16. String sex = request.getParameter("sex");
    17. String city = request.getParameter("city");
    18. // 接收爱好:
    19. String[] hobby = request.getParameterValues("hobby");
    20. // 接收自我介绍
    21. String info = request.getParameter("info");
    22. System.out.println("用户名:"+username);
    23. System.out.println("密码:"+password);
    24. System.out.println("性别:"+sex);
    25. System.out.println("籍贯:"+city);
    26. System.out.println("爱好:"+ Arrays.toString(hobby));
    27. System.out.println("自我介绍:"+info);
    28. // 使用getParameterMap接收数据:
    29. Map map = request.getParameterMap();
    30. for (String key:map.keySet()) {
    31. String[] value = map.get(key);
    32. System.out.println(key+" "+Arrays.toString(value));
    33. }
    34. }
    35. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    36. doGet(request, response);
    37. }
    38. }

    当然,也需要配置Servlet,具体如下:

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>RequestDemo02servlet-name>
    8. <servlet-class>servlet.RequestDemo02servlet-class>
    9. servlet>
    10. <servlet-mapping>
    11. <servlet-name>RequestDemo02servlet-name>
    12. <url-pattern>/RequestDemo02url-pattern>
    13. servlet-mapping>
    14. web-app>

    4、Request对象接收表单请求参数的中文乱码处理

    对于post接收方式,对resuest对象的缓冲区编码进行修改即可,如下: 

    对于get接收方式,需要先以ISO-8859-编码方式获取,再用UTF编码,如下:

  • 相关阅读:
    「C#」异步编程玩法笔记-async、await
    解决方案 | 如何构建市政综合管廊安全运行监测系统?
    数据结构--插入排序
    OS磁盘管理
    vue 数据劫持代理原理
    简单线性回归————损失函数(假设b为0),观察w改变损失函数的情况
    代码随想录算法训练营Day57 | 647. 回文子串 | 516. 最长回文子序列 | 动态规划总结篇
    Filter
    闲人闲谈PS之二十九——关于精确统计工程合同产值问题
    通过隧道功能在安全标准较高的情况下访问Linux
  • 原文地址:https://blog.csdn.net/nuist_NJUPT/article/details/126412065