JSP-复习材料二: Servlet运用

JSP-复习材料二 Servlet运用

1.Servlet概括

1.1.什么是Servlet?

​ Java Servlet 是运行在Web服务器或者是应用服务器上的程序,它是作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器或应用程序之间的中间层。并且能够作为一个连接器,通过交互式地浏览和修改数据,生成动态的Web内容。

1.2 Servlet的运行原理

​ 通过浏览器输入请求地址,浏览器会根据IP地址及端口号找到对应的Web服务器,如果请求的是静态资源,Web服务器直接提供响应;如果请求的是动态资源,则直接请求传递给容器来处理。

​ 能够充当Servlet容器的软件:Tomcat、Weblogic、JBoss等。他们具备管理Servlet组件功能,还具备了Web服务器的一些功能。

​ 组成的核心:Connector、Container。

​ Connector:负责接收浏览器的tcp连接请求,创建一个Request和Response对象来用于和请求端交换数据,然后会产生一个线程来处理这个请求并把产生的 Request 和 Response 对象传给处理这个请求的线程,处理这个请求的线程就是 Container 组件要做的事了。

​ Container 是容器的父接口,所有子容器都必须实现这个接口,Container 容器的设计用的是典型的责任链的设计模式,它有四个子容器组件构成,分别是:Engine、Host、Context、Wrapper。其中Context 代表 Servlet 的上下文,它具备了 Servlet 运行的基本环境。

2. Servlet的配置

2.1 web.xml的配置

1 配置一个 Servlet类,里面包含的配置信息有:

  • 指定Servlet的名字,这个名字在同一个Web应用程序中必须是唯一的
  • 指定Servlet类的完整限定名, 为Servlet指定一个文件描述
  • 为Servlet指定一个简短的名字
  • 为Servlet指定一个图标,在某些图形化界面工具中用于表示该Servlet
  • 定义Servlet的初始化参数,该标签必须包含,可以包含零个或者多个可以包含零个或者多个
    • 定义初始化参数的名字
    • 定义初始化参数的值
    • 为初始化参数提供一个文本描述
    • 指定当web应用程序启动时,Servlet被加载的次数,元素的内容必须是一个整数,如果这个值是负数,或者没有设定该值,Servlet容器将在客户端首次请求这个Servlet时加载它;如果这个值是正数或0,容器将在web应用程序部署时加载和初始化这个Servlet,并且先加载值小的,后加载值大的Servlet。
    • 在Servlet和URL样式之间定义一个映射
    • servlet的名字,必须为元素中声明过的名字
    • 指定对应于Servlet的URL路径
    • 定义上下文的初始化参数,该标签必须包含,可以包含零个或者
    • 定义初始化参数的名字
    • 定义初始化参数的值
    • 为初始化参数提供一个文本描述

提示:

  1. init-param 初始化的参数可以在Servlet类中使用getServletConfig().getInitParameter("param-name")来获取参数值。
  2. context-param 初始化的参数可以在Servlet类中使用getServletConfig().getServletContext().getInitParameter("param-name");来获取参数值。

注意:

  1. init-param只能在当前Servlet类中获取到到参数值。(类成员参数)
  2. context-param 可以在任何 Servlet中获取到参数值。(全局参数)
2.2 Servlet的开发步骤
  • 安装Apache Tomcat 8.0.x
  • 搭建Web项目
  • 项目部署到Tomcat中
  • 测试:打开浏览器访问静态页面
  • 编写java类,继承HttpServlet类,重写doGet和doPost方法
  • 配置web.xml文件
  • 重新部署到Tomcat并测试:打开浏览器访问Servlet

3. HTTP协议

3.1 什么是HTTP协议?

​ HTTP即:【HyperText Transfer Protocol】是由w3c(万维网联盟)制定的一种应用层协议,用来定义浏览器与web服务器之间如何通信以及通信的数据格式的协议。

3.2 HTTP通信原理:

一次请求一次连接,Web服务器可以利用有限的连接为尽可能多的客户端服务。

3.3 Servlet如何处理HTTP协议
3.3.1控制通信数据

当Web容器收到一个HTTP请求时,通信数据由Web容器负责封装和提供,这些信息被解释为两个对象:

  1. 与请求数据对应的是HttpServletRequest类型的对象
  2. 与响应数据对应的是HttpServletResponse类型的对象
3.3.2 HTTPServletRequest对象

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,请求中的所有消息都封装在这个对象中,通过这个对象的相关方法可以获取请求数据。

作用
  1. 读取和写入HTTP请求数据(请求行、消息头等)

  2. 取得和设置Cookies

  3. 取得路径信息

  4. 标识HTTP会话

  5. 实现请求转发:

   //获取转发的请求路径 的转发器        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestb");//        requestDispatcher.include(request,response);        requestDispatcher.forward(request, response);//转发
3.3.3 HTTPServletResponse对象

HttpServletResponse对象代表提供给客户端的响应,封装了HTTP的响应数据。通过这个对象可设置状态行、消息头、实体内容。

作用
  1. 设置对客户端的输出内容
  2. 设置响应的状态码
  3. 设置浏览器的解码方式
  4. 设置Cookies
  5. 实现重定向:response.sendRedirect(“/URI”);记得加后缀
3.4 Servlet如何获取请求参数
3.4.1 HttpServletRequest.getParameter(name)

例如:获取单个的值,常用于单选框http://localhost:8080/test?name=Kitty&age=18

String name = req.getParameter("name");//返回Kitty
String age = req.getParameter("age");//返回 18
String sex = req.getParameter("sex");//返回 null
3.4.2 HttpServletRequest.getParameterValues(name)

例:获取多个的值,常用于复选框http://localhost:8080/test name=Kitty&name=Andy&name=Jack

String[] names = req.getParameterValues("name");//返回 [Kitty,Andy,Jack]
String[] ages = req.getParameterValues("age");//返回 null
3.5 HTTP 8种请求方式

注意:请求方式 区分大小写

请求方式 作用
GET(常用) 请求指定的资源
POST(常用) 向指定的资源提交需要处理的数据
HEAD 要求响应与相应的GET一样,但没有响应体
PUT 上传指定资源
DELETE 删除指定资源
TRACE 返回显服务器收到的请求,主要用于测试或诊断
OPTIONS 返回服务器针对特定资源所支持的HTTP请求方法
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器
3.5.1 GET请求方式:

概述

  • 一般用于向服务器请求指定资源,不会修改页面的内容
  • 它不应该用于一些会造成副作用的操作中(用它来提交数据请求是一种常见的错误用法)
  • 什么情况浏览器发送Get请求:
    • 在地址栏输入一个地址.
    • 点击链接
    • 表单默认提交。method=”get”;默认为get

特点

  • 会将请求数据添加到请求资源路径的后面,所以只能提交少量的数据给Web服务器
  • 请求参数显示在浏览器地址栏上,不安全。如果涉及到密码和账户等私密信息,则最好用POST方式
3.5.2 POST请求方式:

概述

  • 一般用于向服务器提交需要处理的数据,这些数据写在请求的内容(通过流的方式传输)里。可以修改页面内容
  • 什么情况浏览器发送POST请求:
    • 设置表单method属性为POST。method=”post”;
    • 多用于表单输入内容

特点

  • 请求参数添加到实体内容中,可提交大量数据
  • 不会将请求参数显示在浏览器地址栏,相对安全

4. Servlet中文参数乱码问题

4.1解决GET方式时的乱码问题
  1. 确保表单所在的页面按照指定(UTF-8)的字符集打开。

    <html lang="en">
    <head>
         
       <meta http-equiv="Content-Type" content="text/html" charset="UTF-8">
    head>
    <body>
    body>
    html>
    
  2. 如果Servlet容器是Tomcat8.0及之后则正常取值不会出现乱码!因为编码和解码统一了!

    前提是项目工作空间默认编码是UTF-8

  3. 如果Servlet容器是Tomcat8.0之前的则需要先用ISO-8859-1解码,在用UTF-8编码:

    String name = req.getParameter("name");
    byte[] nameBytes = name.getBytes("ISO-8859-1");//ISO-8859-1解码
    name = new String(nameBytes,"UTF-8");//UTF-8编码
    
4.2解决POST方式时的乱码问题
  1. 确保表单所在的页面按照指定(UTF-8)的字符集打开。

  2. 在服务器端读取参数的前面使用 req.setCharacterEncoding("utf-8")设置字符编码为UTF-8即可。

    注:此方法只针对post请求有效

    req.setCharacterEncoding("UTF-8");
    String name = req.getParameter("name");
4.3解决Servlet输出到页面中文乱码的问题

在获取Write/Out对象及调用out方法之前调用setContentType方法及setCharacterEncoding方法

resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
//resp.setHeader("Content-Type","text/html;charset=utf-8");//等价于上面两句代码
resp.getWriter().println("你好," + name + "!");

5.匹配url-pattern的规则

5.1精确匹配

    HelloServlet
    /demo.html

5.2通配符匹配

    HelloServlet
    /*
5.3通配符路径匹配

    HelloServlet
    /shop/*

5.4后缀匹配(常用)

    TestServlet
    *.do

5.5任意匹配

    TestServlet
    /

注意事项

  1. 资源路径 要么只能以/ 开头,要么只能以*开头
  2. /aa/*/bb,这个url是精确匹配了,url必须是 /aa/*/bb,这里的*已不代表通配的含义

6.Servlet生命周期

7.ServletContext对象

        request.setCharacterEncoding("UTF-8");
        String content = request.getParameter("content");
        String realPath = getServletContext().getRealPath("/files/abc.properties");
        System.out.println("realPath:" + realPath);
        FileInputStream fis = new FileInputStream(new File(realPath));
        InputStream is = getServletContext().getResourceAsStream("/files/abc.properties");

        Properties properties = new Properties();//d调用这个文件
        properties.load(new FileReader(realPath));
        String name = properties.getProperty("name");
        String age = properties.getProperty("age");
        String sex = properties.getProperty("sex");
        System.out.println("name:" + name);
        System.out.println("age:" + age);
        System.out.println("sex:" + sex);

8.Servlet线程安全问题

解决办法:

  synchronized (ServletContext.class) {//线程安全
            Object count = getServletContext().getAttribute("count");
            int i = (int) (count == null ? 0 : count);
            getServletContext().setAttribute("count", i + 1);
            response.getWriter().println("ok:" + i);
        }

你可能感兴趣的:(java)