Java服务器端小应用_继承结构_生命周期_请求对象_响应对象

一、重启服务提示

1.update resources:变更了资源,表示修改了静态资源,如HTML。css等

2.update classes and resources:对类的修改使用它不生效,不建议使用

3.Redeploy:重不熟,适用于修改代码,可以重新部署项目到服务器,修改了web.xml冲部署不生效

4.restart server:重启服务器,修改了代码,web.xml,重启服务器

二、web.xml配置Servlet的几种方式

1.通过 web.xml配置了Servlet所在类的全路径,配置了Servlet访问的映射路径。

服务器启动时完成 web.xml的文件加载

<?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">
    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>com.bjsxt.controller.UserServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <!--
            1. url-pattern的值是 /字符 的方式
        -->
        <url-pattern>/UserServlet</url-pattern>

        <!--
            2. url-pattern的值是 *.do的方式,
比如 *.do  那访问该Servlet的时候url这么写:http://ip:port/项目名/xxx.do 只要以.do结尾就行
        -->
        <url-pattern>*.do</url-pattern>

        <!--
            3. url-pattern的值是 多级目录的方式
比如 /user/UserServlet,那访问该Servlet的时候url这么写:http://ip:port/项目名/user/UserServlet
        -->
        <url-pattern>/user/UserServlet</url-pattern>

        <!--
            4. url-pattern的值是 /*,表示拦截所有请求
               那随便写个访问到该项目的url地址,都会访问该Servlet
        -->
        <url-pattern>/*</url-pattern>

        <!--
            5. url-pattern的值是 /,表示拦截所有请求,但是不拦截 jsp文件
               除了访问jsp外,访问其他的资源都会访问到该Servlet
        -->
        <url-pattern>/</url-pattern>

        <!--
            说明:一个Servlet可以配置多个url-pattern,但是多个Servlet不能配置相同的url-pattern,
            这样的话请求过来后tomcat不知道该调用哪个Servlet进行处理
        -->
    </servlet-mapping>
</web-app>
2.web.xml配置欢迎页面

默认欢迎页就是指,浏览器发出的请求路径中没有指定具体的访问资源时,默认就会访问的页面。

在Tomcat中的conf/web.xml中配置了全局的几个默认欢迎页。

欢迎页可以配置多个,匹配优先级自上而下。

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

 一般在我们项目中要设置默认欢迎页的话,在自己项目的web.xml中设置即可!不要改Tomcat中的conf/web.xml进行设置。

<welcome-file-list>
    <welcome-file>hello.html</welcome-file>
</welcome-file-list>

 三、Servlet的继承结构

1.概述

tomcat服务器提供了Servlet规范的实现。代码想要被服务器调用,必须遵守Servlet规范

自定义的Servlet类并没有去直接实现Servlet接口,是因为该接口中方法比较多,Servlet接口有它的一系列实现类,我们继承实现类就简介的实现Servlet接口。

 

2. 继承结构体系
2.1 Servlet接口
  1. init(),创建Servlet对象后立即调用该方法完成一些初始化工作。--初始化

  2. service(),处理客户端请求,执行业务操作,可以利用响应对象响应客户端请求。

  3. destroy(),在销毁Servlet对象之前调用该方法。

  4. getServletConfig(),ServletConfig是容器向servlet传递参数的载体。

2.2ServletConfig接口 
  1. String getServletName(),返回 Servlet 的名字,即 web.xml 中 <servlet-name>元素的值。

  2. ServletContext getServletContext(),返回一个代表当前 Web 应用的 ServletContext 对象。

  3. String getInitParameter(String name),根据初始化参数名返回对应的初始化参数值。

  4. Enumeration getInitParameterNames(),返回一个 Enumeration 对象,其中包含了所有的初始化参数名。

 

2.4 HttpServlet类

继承自 GenericServlet,针对于处理 HTTP 协议的请求所定制。在 HttpServlet的service() 方法中已经把 ServletReuqest 和 ServletResponse 转为 HttpServletRequest 和 HttpServletResponse。 直接使用 HttpServletRequest 和 HttpServletResponse, 不再需要强转。  

2.5总结 

 tomcat服务器在接收到浏览器的请求后,会调用Servlet的service方法处理器请求,如果当前自定义的Servlet类没有service方法会调用父类的service方法进行处理。

 四、Servlet生命周期

1.执行过程

Servlet的生命周期是由容器管理的,分别经历三各阶段:

反射:实例化对象

init():初始化

service():服务

destroy():销毁

 1.编写Servlet
public LifeServlet() {
        System.out.println("LifeServlet 创建了");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("LifeServlet 初始化了");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LifeServlet 执行了");

        //获取ServletConfig对象 getServletConfig()
        ServletConfig servletConfig = getServletConfig();
        //获取web.xml中servlet的servlet-name的值
        String servletName = servletConfig.getServletName();
        System.out.println(servletName);
        //获取初始化参数值
        String name = servletConfig.getInitParameter("name");
        System.out.println(name);
        //获取所有初始化参数名
        Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
        while (initParameterNames.hasMoreElements()){
            String s= initParameterNames.nextElement();
            System.out.println(s+"--"+servletConfig.getInitParameter(s));
        }
    }

    @Override
    public void destroy() {
        System.out.println("LifeServlet 销毁了");
    }
2.配置Servlet
<servlet>
        <servlet-name>LifeServlet</servlet-name>
        <servlet-class>Servlet.LifeServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LifeServlet</servlet-name>
        <url-pattern>/LifeServlet</url-pattern>
    </servlet-mapping>
3.启动服务器,并三次访问

只在第一次访问的时候创建和初始化一次

4.停止服务器

 5.在web.xml中添加load-on-startup的配置
<servlet>
        <servlet-name>LifeServlet</servlet-name>
        <servlet-class>Servlet.LifeServlet</servlet-class>
        <!--
       load-on-startup就是在启动服务器时就创建并初始化Servlet对象
       数字越小,优先级越高。
         -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>LifeServlet</servlet-name>
        <url-pattern>/LifeServlet</url-pattern>
    </servlet-mapping>
6.重启服务器

7.三次访问的结果

 

2.问题

 问题1:Servlet对象创建、初始化并使用完后会销毁吗?

Servlet对象在创建、初始化并使用后不应该销毁。如果使用完(请求处理完)就销毁,那么下次过来请求又得去创建Servlet对象,这样效率并不高!!

我们自始至终都使用同一个Servlet对象去处理请求,如果同时有10个请求过来访问Tomcat服务器,服务器会创建10个线程来处理请求,避免使用全局变量, 多个线程操作全局变量存在线程安全的问题, service()方法中的局部变量不存在线程安全问题。

问题2:Servlet对象会被创建及初始化几次?

Servlet对象只会被创建及初始化一次。之后会驻留在内存当中。

问题3:Servlet对象是在什么时候创建及初始化的?

Servlet的创建与初始化的时机有两个:

  1. Servlet在第一次被浏览器访问的时候创建与初始化的(目前我们的代码用的就是这种方式,默认就是这种)。

  2. Servlet在启动服务器的时候被创建与初始化的(该方式需要做一些配置,告诉Tomcat服务器在启动的时候就创建Servlet对象)。load-on-startup

问题4:Servlet对象什么时候销毁?

Servlet对象是由Tomcat服务器创建的,之后就一直驻留在内存中处理请求。直到服务器停止后,Servlet才会被销毁。

3.总结

        当客户端浏览器第一次请求Servlet时,容器会实例化这个Servlet,如果配置了load-on-startup启动容器时就会完成servlet的创建,然后调用一次init方法,并在新的线程中执行service方法处理请求。service方法执行完毕后容器不会销毁这个Servlet而是做缓存处理,当客户端浏览器再次请求这个Servlet时,容器会从缓存中直接找到这个Servlet对象,并再一次在新的线程中执行Service方法。当容器在销毁Servlet之前对调用一次destroy方法。

 没有配置load-on-startup的情况

 

配置了load-on-startup的情况:

        服务器启动的时候就会执行:构造方法,然后执行初始化方法。之后有请求过来,就直接走service方法进行处理。服务器停止的时候,执行销毁方法。

 五、Servlet使用流程总结

  1. 打开IDEA

  2. 在IDEA中创建一个Java Enterprise项目

    1. 配置本机的Tomcat服务器,第一次需要配置,后续不需要再配置。

    2. 勾选Web Application,创建web引用程序,自动创建web.xml。

  3. 在项目的src目录下创建一个com.bjsxt.servlet包,在包中创建自己的类继承HttpServlet。

  4. 重写service方法,doGet方法,doPost方法,在方法中写的就是处理请求的业务逻辑代码。

  5. 在web.xml中配置映射关系,配置servlet的访问路径。

  6. 启动tomcat服务器,tomcat服务器会解析web.xml。

  7. 在浏览器输入路径访问Servlet

    tomcat接收到客户端的请求后,会创建请求与响应对象,调用请求的serlvet执行service方法,将创建的请求与响应对象以参数的形式传递到service方法中。

 六、Servlet代码执行流程

  1. tomcat服务器启动时,会加载解析我们项目的web.xml文件。

  2. tomcat服务器根据解析的结果,创建所有在web.xml中配置的Servlet对象(假设都配置了load-on-startup)。

  3. tomcat服务器将所有创建好的Servlet对象以键值对的形式放在内存中,键是你配置的url-pattern,值是Servlet对象。

  4. 在浏览器地址栏输入url地址,比如:http://localhost:8080/demo/Hello

  5. tomcat服务器接收到浏览器发送的http请求,然后进行解析,得到本次请求的两个对象,HttpServletRequest和HttpServletResponse。

  6. tomcat服务器解析url地址中要访问的资源,根据资源路径找到提前创建好的Servlet对象。

  7. tomcat服务器根据反射调用Servlet对象的service方法,并将此次请求解析出的request和response对象传递给service执行。

  8. service方法执行完后,tomcat会按照http响应的格式将数据响应给浏览器。

  9. 浏览器接收到tomcat的响应结果后,对其进行解析,以网页的形式展示给用户看。

 七、请求对象(HttpServletRequest)

1.get和post的区别
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。

  • GET请求只能进行url编码,而POST支持多种编码方式。

  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

  • GET请求在URL中传送的参数是有长度限制的,而POST则没有。

  • 对参数的数据类型GET只接受ASCII字符,POST既可是字符也可是字节。

  • GET相比POST来说不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

  • GET参数通过URL传递,POST放在Request body中。

 2.service方法的强调

作用:在service方法中编写处理请求的业务逻辑代码,浏览器发送请求后由tomcat服务器自动调用执行。

步骤:

service方法中写业务逻辑代码的话,大概是如下三步:

  1. 接收请求(获取请求数据)

  2. 处理请求

  3. 完成响应

 3.HttpServletRequest对象获取请求数据
 1.request对象的来源

        浏览器发送请求后,由tomcat服务器接收到,然后对请求的信息进行解析,将解析结果封装到HttpServletRequest和HttpServletResponse两个对象中。然后tomcat调用service方法的时候,又将这两个对象传递给了service方法。

 2.request对象的特点
  1. 在tomcat服务器接收请求后,对请求进行解析后创建的。

  2. 每次请求,tomcat服务器都会重新创建。

  3. request对象存储了此次请求的所有数据(http协议中的请求行、头、体)。

 3.request对象使用的案例
/**
 * 浏览器发送请求,服务器接收请求,解析访问的资源,服务器自动的创建请求 和 响应对象,传递给service方法
 * req:请求对象(例如:请求行,头,体中的数据)
 * resq:响应对象(例如:相应行,头体【响应回到浏览器中的内容】)
 */
public class RequestServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /* 获取请求行中的数据*/
        //获取请求方式
        String method = req.getMethod();
        System.out.println(method);
        //获取请求的URI
        String requestURI = req.getRequestURI();
        System.out.println(requestURI);
        //获取请求的URL
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL);
        //获取请求协议
        String protocol = req.getProtocol();
        System.out.println(protocol);

        //获取请求头中数据
        String header = req.getHeader("Accept");
        System.out.println(header);
        //获取所有的请求头信息
        //拿到所有请求头的名字
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String s = headerNames.nextElement();
            System.out.println(s +":"+req.getHeader(s));
        }
        //getParameterValues()方法可以获取多个参数名一样的数据,会得到一个数组
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println("爱好是:" + Arrays.toString(hobbies));
    }
}
4.数据乱码问题解决

        目前我们在请求体中如果携带的请求数据存在中文,在后台使用req.getParameter方法获取的时候会出现乱码,出现乱码的本质原因是因为编码与解码方式不一致导致的。Tomcat服务器接收到请求后,会解析请求,并将请求中的数据给封装到HttpServletRequest对象中。所以,我们对request对象中的数据进行重新编码即可。

在service方法中第一行加入如下代码:

注意:

在Tomcat8.0及以后,不管是get请求还是post请求,都只需要设置req.setCharacterEncoding("utf-8");即可解决请求乱码。在Tomcat8.0之前,如果是通过get请求接收到的参数发生乱码的话,可以通过如下方式解决:

String s = new String(req.getParameter("name").getBytes("iso-8859-1"),"utf-8");

这行代码必须要放在req.getParameter()之前才能生效!!

 八、响应对象(HttpServletResponse)

 

1. response对象的作用

 响应对象,用来响应浏览器发起的请求,其中封装了响应结果数据及客户端的一些信息等。

2. response对象的特点
  1. 由Tomcat接收到请求后完成创建,并作为实参传递给对应的service方法使用

  2. 每次请求都会重新创建,请求结束后即销毁。

  3. 程序员在service方法中直接调用即可。

  4. HttpServletResponse是一个接口,service方法接收到的是实例化对象。

3. response对象的使用

 使用respose对象完成数据的响应

        response对象是由Tomcat收到请求后实例化创建的,我们直接调用它的响应方法即可,Tomcat底层会将response响应的内容自动转换为HTTP协议的格式,输出给浏览器。

         响应方法: ​ response.getWriter().write(“响应内容”); 底层是本质就是网络编程的流输出。

         ​ 注意:响应内容可以直接是数据,也可以是数据+HTML标签+CSS样式+JS脚本。

4.使用response对象设置响应头

         使用response对象完成响应的时候,Tomcat会自动将响应内容转换为HTTP的响应格式,但是同时我们也可以使用response对象自定义设置响应头。

 

//setHeader()方法作用:设置响应头,key相同的话,后面设置的值会覆盖前面设置的
resp.setHeader("key1", "value1");
resp.setHeader("key2", "value2");
resp.setHeader("key1", "value1_1");

//addHeader()方法作用:设置响应头,key相同的话,后面设置的值不会覆盖前面设置的
resp.addHeader("name1", "value1");
resp.addHeader("name2", "value2");
resp.addHeader("name1", "value1_1");

//下面两行代码是等价的
resp.setContentType("text/html;charset=utf-8");//设置响应的数据类型及解码方式
resp.setHeader("Content-Type", "text/html;charset=utf-8");//设置响应的数据类型及解码方式
 5.响应数据乱码问题解决

目前我们在后端service方法中使用response对象响应浏览器时,如果响应结果中存在中文,会在浏览器中出现乱码。因为Tomcat服务器默认使用utf-8的编码格式编码响应数据,而浏览器默认使用ISO-8859-1来解析响应数据。

解决:告诉浏览器使用utf-8的方式来解析数据。

resp.setContentType("text/html;charset=utf-8");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值