Servlet基础教程

目录

Servlet简介

1、Servlet的生命周期

2、Servlet的运行原理   

Servlet的组织结构

3、Servlet处理HTTP协议/请求方式

Servlet处理参数值

Servlet如何处理HTTP协议

请求方式

转发器

4、Servlet处理请求资源路径

Servlet组件的合并

5、重定向

6、异常错误处理


Servlet简介

    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。


1、Servlet的生命周期

Servlet 的生命周期可分为:实例化,初始化,就绪,销毁。

 init(): 在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。

service(): 它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。

destroy(): 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。Servlet的工作过程

阶段1:实例化
               即容器调用构造器创建Servlet对象.
               时机1:容器收到请求后,创建Servlet对象
               时机2:容器启动后,立即创建Servlet对象
                   web.xml中需要配置
                   <load-on-startup>1</load-on-startup> 
阶段2:初始化
               容器在创建Servlet对象后,会立即调用init方法进行对象的初始化。一般情况下,我们不需要重写此方法,因为父类型GenericServlet里提供了init方法的实现逻辑。此方法保存了另外一个对象ServletConfig的引用,如果你想初始化一些自定义的属性,我们可以将初始化的值配置在web.xml里。
       

<init-param>
      <param-name>company</param-name>
      <param-value>华育兴业</param-value>
</init-param>

通过ServletConfig提供的 getInitParameter(String name)来获取值       

public void init() throws ServletException {
		System.out.println("----初始化");
		ServletConfig config = getServletConfig();
		String company = config.getInitParameter("company");
	}


阶段3:就绪
             初始化之后,容器调用Servlet对象的service方法进行资源分配。
阶段4:销毁
             容器会根据自己的算法来进行Servlet对象的销毁,销毁前一定会调用destroy()方法。因此我们可以重写此方法来完成一些业务逻辑。卸载程序时,一定会销毁Servlet对象      

public void destroy() {
		System.out.println("程序卸載了");
	}

练习代码:

public class HelloServlet  extends HttpServlet{
	private String company;
	private String manager;
	
	public HelloServlet() {
		System.out.println("创建servlet对象");
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("处理业务逻辑");
		System.out.println("company:"+company);
		System.out.println("manager:"+manager);
	}

	@Override
	public void init() throws ServletException {
		System.out.println("----初始化");
		ServletConfig config = getServletConfig();
		company = config.getInitParameter("company");
		manager = config.getInitParameter("manager");
	}
	
	@Override
	public void destroy() {
		System.out.println("程序卸載了");
	}
}

2、Servlet的运行原理   

  1. 浏览器依据IP和PORT与服务器建立连接
  2. 发送请求数据包到服务器
  3. 服务器创建Servlet组件对象
  4. 使用HttpServletRequest处理请求数据包(读取页面上的数据)
  5. 使用HttpServletResponse封装响应数据(将程序中的数据发送到页面上)
  6. 服务器发送响应数据包
  7. 浏览器进行解析,生成页面

Servlet的组织结构

appName
    ---》WEB-INF
         ---》classes
             ---》xxx.class文件
    ---》lib(可选)
    ---》web.xml
    ---》index.html(可选)


3、Servlet处理HTTP协议/请求方式

Servlet处理参数值

Servlet处理页面上出入的值request调用下面方法

 处理1:1形式的参数与参数值
      String getParameter(String name)
      如果name不存在,返回null
   处理1:M形式的参数与参数值
      String[] getParameterValues(String name)
      如果name不存在,返回null

Servlet如何处理HTTP协议

当浏览器向服务器端发送请求后,服务器端会维护两个对象,用来封装和处理请求数据包的数据,及其响应数据。分别是HttpServletRequestHttpServletResponse对象
    1、HttpServletRequest对象封装和处理请求数据包的数据(接收页面发来的数据)
       提供了以下方法
       String getParameter(String name)
       String[] getParameterValues(String name)
       String getHeader(String str)
       Enumration<E> getHeaders()
       RequestDispatcher getRequestDispatcher(String url)
       .......
    2、HttpServletResponse对象封装和处理服务端要响应给浏览器的数据(将封装好的数据发送给浏览器)
       提供了以下方法
       void setContentType(String str)
       void sendRedirect(String url)
       .......

请求方式

浏览器向服务器发送请求的种类有八种:
      GET,POST,OPTIONS,HEAD,PUT,DELETE,TRACE,CONNECT
      (1)常用的两种getpost
          get向特定资源发送请求(如返回登陆界面),在地址栏上直接写地址,表单的默认提交
          post向指定资源提交数据(提交表单,上传文件),要想使用此种方式提交,表单的method属性设置POST
      (2)两者的区别
          get提交的数据会显示在地址栏上,数据量小,最多为4kb。不安全
          post提交的数据不会在地址栏上显示。因此我们可以提交大量的数据,相对安全

转发器

     概念:一个web组件将未完成的任务交给另一个web组件继续做,通常是一个servlet将数据获取之后转交给jsp进行展现.

     下面讲的是三种转发中较为常用的一种转发方式和步骤

     转发步骤:

         1、绑定数据

                request.setatteribute(string name,obj)   name绑定名 obj:绑定值   服务器端使用

          2、获取转发器

                requestdispatatcher rd = request.getrequestdispatcher(string url)  url 要转发到的路径

           3、启动转发

                rd.forward(request,response)   

                   注:转发的本质是一个web组件通知容器调用另外一个web组件,(即调用service方法,所以需要传递request,response)

     页面获取数据:

               obj request.setAttribute(string name);//依据绑定名获取绑定值,返回时时object类型的,需要强转后使用

练习代码:

protected void service(HttpServletRequest req, HttpServletResponse resp){
   
    //服务器端
    String str = "转发器测试";
	/** 绑定数据*/
	req.setAttribute("key", emp);
	/** 获取转发器*/
	RequestDispatcher rd = req.getRequestDispatcher("emplist.jsp");
    /**启动转发*/
	rd.forward(req, resp);
}
/**========================================================================*/
//页面
<% String str = (String) request.getAttribute("key"); %>

4、Servlet处理请求资源路径

web.xm基礎l配置

<servlet>
	<!--名称(随便起) -->
	<servlet-name>count</servlet-name>
	<!-- 要执行的servlet的路径 -->
	<servlet-class>com.hyxy.session.CountServlet</servlet-class>
</servlet>
<servlet-mapping>
	<!--也是名称(要和上面的名称一致) -->
	<servlet-name>count</servlet-name>
	<!-- 浏览器上要访问的路径名称(绝对路径下必须要有/ 后面的名称可以随便起) -->
	<url-pattern>/count</url-pattern>
</servlet-mapping>

1、什么是请求资源路径
         浏览器中的网址  http://ip:port/appName/url-pattern,请求资源路径:appName/url-pattern
2、处理原理
         浏览器依据ip和port确定服务器,之后依据appName确定应用程序所在的目录,servlet容器默认浏览器请求的是一个Servlet组件, 所以会校验web.xml里的url-pattern,进行匹配,执行相关的Servlet组件。
3、精确匹配
         服务器在进行web.xml里的url-pattern的校验时,会严格匹配请求路径是否一致,如果匹配成功,就会执行相关资源
         如: <url-pattern>/hello.html</url-pattern>严格匹配成功后,即使程序中有hello.html页面,也不会返回这个页面,而是执行相关Servlet。
4、通配符匹配
         通配符: *  ,匹配0个或多个字符,必须使用斜杠
              如:<url-pattern>/*</url-pattern>       
                    http://ip:port/appName/abc.html   匹配成功
                    http://ip:port/appName/service/add.html   匹配成功
                    http://ip:port/appName/listEmp   匹配成功      
5、后缀匹配 
         在写web.xml里的url-pattern的值时,我们可以使用“  * .  后缀的方式,后缀可以是1或多个字符组成的。
         如:<url-pattern>*.action</url-pattern>
              http://ip:port/appName/abc.html   匹配失败    
              http://ip:port/appName/emp/abc.action   匹配成功
              http://ip:port/appName/listEmp.action  匹配成功
          
       优先级: 精确匹配最高         
           假如:web.xml中有三个Servlet组件,其url-pattern如下
         <url-pattern>/abc.do</url-pattern>
         <url-pattern>/*</url-pattern>
         <url-pattern>*.do</url-pattern>
         
           浏览器地址:http://ip:port/appName/abc.do 会执行精确匹配的Servlet组件如果精确匹配,通配符匹配,后缀匹配都没有成功,容器会查找是否有此文件,如果有此文件,打包数据返回给浏览器。如果没有,返回404.     

Servlet组件的合并

一般情况下,Servlet组件充当的角色为控制角色,控制角色的
          作用是接收请求后进行分发到不同的资源里。因此一个Servlet就可以
          对请求资源路径进行分析,使用分支结构来处理不同的资源。
                 
           如何合并:
      (1)采用后缀匹配进行修改web.xml
      (2)获取请求资源路径进行分析,然后使用if分支进行处理

      

5、重定向

    1.概念:服务器处理完业务逻辑后,向浏览器发送一个状态码302,同时发送一个消息头Location,此消息头的值是一个新地址。当浏览器接收这些信息后,会立即向服务器发送该地址的请求
    2、重定向的原理:可以参考:https://blog.csdn.net/kobejayandy/article/details/13745545
    3、如何重定向
            response.sendRedirect(String url)    url:是重定向的新地址
    4、重定向的特点
            地址栏的地址会发生改变。
            重定向之前不能关闭流
            两次请求不共享request和response对象  

6、异常错误处理

    错误代码及其解决方法:
           服务器在处理完业务逻辑后,会响应浏览器,响应的内容包含了状态编码(数字类型)
           200:表示成功处理业务。
           404:服务器处理的路径存在问题,找不到相关请求资源
                    如:
                      (1)在地址栏上的路径有问题(大小写不对)
                      (2)<url-pattern>的值与地址栏路径不一致
                      (3)两个servlet-name不一致
                      (4)没有部署项目
                      (5)项目的组织结构有问题
           405:容器找不到Servlet组件的service方法
                      (1)方法名写错
                      (2)方法的参数类型有问题
                      (3)方法的异常,返回值有问题
           500:容器找不到Servlet组件
                      (1)没有继承HttpServlet或实现Servlet接口
                      (2)<servlet-class>写的不错
                      (3)service里的逻辑出现了问题

    处理中文参数值

           中文会出现乱码,原因是编码与解码的字符集不一致造成
           中文乱码解决方式   
                  方式1:服务端先编码再解码,适合 get/post  req.setCharacterEncoding("utf-8")  服务器端默认使用iso-8859-1解码浏览器端常用的为utf-8进行编码
                  方式2:只适合post request.setCharacterEncoding("utf-8")  位置:处理请求参数前   
           发送响应时:
                  response.setContentType("text/html;charset=utf-8")  位置:写在获取流之前 

再写代码时先将request.setCharacterEncoding("utf-8")response.setContentType("http/html;charset=utf-8") 写上这样就能避免出现乱码

猜你喜欢

转载自blog.csdn.net/woainiqazwsx123/article/details/82776314
今日推荐