Servlet

一、Servlet实现
1、Servlet简介
Servlet 是 Server 与 Applet 的缩写,是服务端小程序的意思。使用 Java 语 言编写的服务 器端程序,可以像生成动态的 WEB 页,Servlet 主要运行在服务器端,并由服务器调用执行, 是一种按照 Servlet 标准来开发的类。 是 SUN 公 司提供的一门用于开发动态 Web 资源的技 术。(言外之意:要实现 web 开发, 需要实现 Servlet 标准) 。
Servlet 本质上也是 Java 类,但要遵循 Servlet 规范进行编写,没有 main()方法,它的创 建、使用、销毁都由 Servlet 容器进行管理(如 Tomcat)。(言外之 意:写自己的类,不用写 main 方法,别人自动调用)
Servlet 是和 HTTP 协议是紧密联系的,其可以处理 HTTP 协议相关的所有 内容。这也是 Servlet 应用广泛的原因之一。
提供了 Servlet 功能的服务器,叫做 Servlet 容器,其常见容器有很多,如 Tomcat, Jetty, WebLogic Server, WebSphere, JBoss 等等。
2、实现Servlet步骤
* 实现步骤

新建普通java类
实现Servlet规范-----继承HTTPServlet类
重写service方法:
    在servlet中默认情况下,无论你是get还是post 提交过来 都会经过service()
    方法来处理,然后转向到doGet 或doPost
配置web.xml,配置对外访问路径
将项目发布到服务器并运行服务器
通过浏览器访问项目中的资源
*  实现Servlet规范的三种方式
        方式一:继承HttpServlet类
        方式二:继承GenericServlet类
        方式三:实现Servlet接口
*  访问路径
注意 url 的 格式正确,tomcat 的端口为 8080。
 http://localhost:8080/hw/helloweb
 协议:http
 域名和端口号指定服务器:localhost:8080(如果没有更改)
 站点名:hw(项目的context root,通过站点找到服务器下的具体项目)
 资源名:helloweb(web.xml中配置)

3、配置web.xml

基本配置

 
  
    servlet01  
    com.shsxt.servlet.Servlet01 
  
  
    servlet01  
    /ser01 
  
* 详细配置
 *  1、初始化参数
 *      设置在web.xml中的servlet标签中
 *      
 *          
 *          
 *      
 *  2、自启动(服务器启动时自动实例化servlet)
 *      设置在web.xml中的servlet标签中,要写在init-param标签之后
 *      1
             Servlet 容器启动时加载 Servlet 对象的顺序   
 *      值越小,优先级越高
 *  3、servlet配置多个访问路径
 *      以Servlet05为例:
 *      a. 只设置一个路径
 *          /ser05
 *      b.设置多个路径
 *          /ser05
 *          /ser005
 *      c.以指定路径开头的所有资源路径
 *          /test/*
 *      d.以指定后缀结尾的所有资源路径
 *          *.html
 *      e.所有路径都可以访问
 *          *
 *      
 *      通配符"*"
 *          1、"*"只能放在最前面或者最后面,不能放在中间,不能单独使用,不能和字母拼接
 *          2、值越精准,优先级越高
 *
 *  4.注意事项:
        1、web.xml改动之后必须重启服务器        
        2、url-pattern的值必须唯一
                    异常:
            java.lang.IllegalArgumentException: 
                     The servlets named [servelt01] and 
                     [servlet02] are both mapped to the 
                     url-pattern [/ser01] which is not permitted    
        3、servlet-mapping标签中的servlet-name的值必须是已存在的值
            (servalet标签中的servlet-name)
                    异常:
            java.lang.IllegalArgumentException: 
                     Servlet mapping specifies an unknown 
                     servlet name servelt02
        4、servlet标签中servlet-name要与servlet-mapping标签中的
            servlet-name的值保持一致 (servlet标签中servlet-name存在)
            如果不一致,代码不会报错,只是访问的不是你的指定资源
        5、servlet标签中的servlet-class的路径不能写错
                    异常:
            java.lang.ClassNotFoundException:
                   com.shsxt.servlet.Servlet04
        6、servlet-mapping标签中的url-pattern的值前面必须加"/"
                    异常:
            java.lang.IllegalArgumentException: 
                     Invalid  ser01 in servlet mapping
        7、servlet标签中的servlet-name的值必须唯一
                    异常:
            Duplicate unique value [servlet01] declared for 
                     identity constraint "web-app-servlet-name-uniqueness" 
                     of element "web-app".  
url-pattern配置示例:客户访问的 Servlet 的相对 URL 路径  

  
  
    servlet05
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*
    
  
说明: url-pattern 可以配多个(一个 servlet 可以通过多个 url-pattern 访 问)
但多个 servlet不能 配置成同一个 url-pattern

4、Servlet生命周期
Servlet 没有 main()方法,不能独立运行,它的运行完全由 Servlet 引擎来控 制和调度。 所谓生命周期,指的是 servlet 容器何时创建 servlet 实例、何时调 用其方法进行请求的处理、 何时并销毁其实例的整个过程。(此处讨论默认的生 命周期)
* 实例和初始化时机
初始化,服务器方式,由服务器调用
只会调用一次,当第一次请求时
当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会创建实例并进行初始化
* 就绪/调用/服务阶段
服务/调用方法,服务器方式,由服务器调用
可以调用多次,每次请求到达时都会调用
* 销毁时机
服务器方式,由服务器调用
只会调用一次,容器关闭时(正常关闭时才会打印)
5、 Tomcat 与 Servlet 交互时序


clipboard.png
1、Web Client 向 Servlet 容器(Tomcat)发出 Http 请求  
2、Servlet 容器接收 Web Client 的请求  
3、Servlet 容器创建一个 HttpRequest 对象,
    将 Web Client 请求的信息封 装到这个对象 中  
4、Servlet 容器创建一个 HttpResponse 对象  
5、Servlet 容器调用 HttpServlet 对象的 service 方法,把 HttpRequest对 
象与 HttpResponse 对象作为参数,传给 HttpServlet 对象  
6、HttpServlet 调用 HttpRequest 对象的有关方法,获取 Http 请求信息  
7、HttpServlet 调用 HttpResponse 对象的有关方法,生成响应数据  
8、Servlet 容器把 HttpServlet 的响应结果传给 Web Client 

6、Servlet的工作原理及流程(重点)


clipboard1.png

1)客户端发出请求
2)根据 web.xml 文件的配置,找到对应的站点和资源
3)读取XML文件中的值找到对应的 找到该 class 并加载执行该 class
4)返回结果 由 Web 服务器将结果响 应给客户端
二、请求的几种方式
客户端对服务器发起请求的几种方式:
地址栏直接输入、超链接、Form表单、ajax、请求转发、重定向
三、常用对象HttpServletRequest对象
HttpServletRequest 对象:主要作用是用来接收客户端发送过来的请求信息
1、常用方法

// 获取请求的完整路径 (从http到"?"前面)
getRequestURL()
// 获取请求的部分路径 (从端口后"?"前面)
getRequestURI()
// 获取请求的参数字符串 (从"?"开始到最后)
getQueryString()
// 获取请求类型  (GET/POST)
getMethod()
// 获取指定请求头
getHeader( String)
// 获取指定名称的参数值(重点)
getParameter(String);

2、请求乱码问题(GET/POST、Tomcat版本)
解决POST请求乱码:
request.setCharacterEncoding("UTF-8"); // 设置服务器的编码方式,该方式只对post请求生效,如果是get请求没有任何效果
new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
解决GET请求乱码:(如果原来不乱码,通过new String()去处理,会出现另外一种乱码)
new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");

总结 :
Post请求:无论什么版本的服务器,都乱码
Get请求:Tomcat8及以上版本,不乱码;Tomcat7及以下版本乱码。

3、请求转发(重点)
request.getRequestDispatcher(url).forward(request, response);
特点:
服务器行为
地址栏不会发生改变
只有一次请求,request对象共享
注意:使用之前不能关闭资源
4、request域对象(重点)
将数据存到request作用域中,前台页面(JSP)从作用域中获取域对象的值

方法: 
 *  setAttribute(name,value):设置作用域,name是字符串类型,value是object类型
 *  getAttribute(name):获取指定名称的域对象的值,返回的是object类型
 *  removeAttribute(name):移除指定名称的域对象的值
 作用范围:
     在一次请求中有效,即 服务器跳转有效。
     request 域对象中的数据在一次请求中有效,则经过请求转发,request 域 
     中的数据依然存在,则在请求转发的过程中可以通过 request 来传输/共享数据。

四、常用对象HttpServletResponse对象
1、常用方法

// 设置响应头
// response.addHeader("uname", "zhangsan");     
// 设置错误状态
// response.sendError(404,"由于颜值过低,无法访问!");      
// 设置refresh响应头
// response.setHeader("refresh", "2"); // 2秒刷新一次
response.setHeader("refresh", "2;URL=http://www.baidu.com"); 
// 2秒钟后跳转到百度

2、响应数据

getWriter()获取字符流(只能响应回字符);
getOutputStream()获取字节流(能响应一切数据)。
response.setContentType("application/json");// 设置响应类型  默认是纯文本
    响应回的数据到客户端被浏览器解析。
    注意:两者不能同时使用。

3、响应乱码问题
* 乱码原因:
在响应时,服务器经过网络传输响应数据到客户端,服务器默认编码为ISO-8859-1,该编码不支持中文;客户端也有其默认编码。
总结:1)服务端和客户端编码不一致;2)编码不支持中文。
* 如何解决
1)统一客户端和服务端编码格式;2)使用支持中文的编码格式

getWriter()的字符乱码 
    响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,
    该编码方式并不支持中文。
1)// 设置服务端的编码
   //response.setCharacterEncoding("UTF-8");    
   // 设置客户端的编码
   //response.setHeader("content-type", "text/html;charset=UTF-8");
2)// 同时设置客户端和服务端的编码
   response.setContentType("text/html;charset=UTF-8");  
   
        //分别指定服务器和客户端编码
        response.setCharacterEncoding("utf-8");
        response.setHeader("content-type", "text/html;utf-8");  
        //或同时指定服务器和客户
        //response.setContentType("text/html;charset=utf-8");           
        
        String str="

阿拉灯神丁

"; OutputStream os=response.getOutputStream(); os.write(str.getBytes()); os.close();

getOutputStream()字节乱码 
    对于 getOutputStream()方式获取到的字节流,响应中文时,由于本身就是传输的字节,
    所以此时可能出现乱码,也可能正确显示。
    无论如何我们都应该准确掌握服务器和客户端使用的是那种编码格式, 以确保数据正确显
    示。指定客户端和服务器使用的编码方式一致即可 。 

4、响应图片
有的时候我们并不知道(或不能确定)图片的路径,需要通过请求服务器资源动态地响应图片给客户端。这种方式和文件拷贝的理念是一致的,客户端请求 服务器的资源,在服务端获取到真实的图片资源,通过输入流读取到内存,然后通过输出流写出到客户端即可。

步骤:
    得到图片存放的路径
    通过路径得到文件对象
    得到字节输出流
    得到文件对象的输入流
    循环读取,并写出到浏览器 
注意:在客户端解析资源时默认是以文本(text/html)的形式,当 响应图片时需要指定
      响应头信息,告知客户端响应内容为图片形式,使用一种 叫做 MIME 类型的东西来
      指定。MIME 类型见 Tomcat 的 web.xml 文件。       
   //设置响应类型
        response.setContentType("image/jpeg");
        //得到图片的响应路径
        String path=request.getServletContext().getRealPath("/image/s.jpg");
        //通过路径得到文件对象
        File file=new File(path);
        //得到字节输出流
        OutputStream os=response.getOutputStream();
        //得到文件对象的输入流
        InputStream is=new FileInputStream(file);
        //循环读取
        byte[] arr=new byte[1024];
        int len=0;
        while((len=is.read(arr))!=-1){
            os.write(arr);      
        }
        os.flush();
        is.close();
        os.close();

5、重定向
重定向是一种服务器指导,客户端的行为。
客户端发出第一个请求,被服务器接收,经过处理服务器进行响应。
与此同时,服务器给客户端一个地址(下次请求的地址 resp.sendRedirect("url");)。
当客户端接收到响应后,立刻、马上、自动根据服务器 给的地址进行请求的发送第二个请求。
服务器接收请求并作出 响应,重定向完成。
从描述中可以看出重定向当中有两个请求存在,并且属于客户端行为。

请求转发和重定向的区别
        1、请求转发是服务端跳转,重定向是客户端跳转
        2、请求转发只有一次请求,重定向有两次请求
        3、请求转发地址栏不发生改变,重定向地址栏会改变
        4、请求转发request域对象能共享,重定向不能共享
        5、请求转发只能请求当前资源下的路径,重定向可以任意地址

  response.sendRedirect("http://www.baidu.com");    

6、请求路径问题
路径分为相对 路径和绝对路径
* 绝对路径
可简单理解为完整路径,在 web 项目中绝对路径分 两种,一种是以 http://开头的,该种绝对路径已经跨域,即任何地方的资源都能 访问,另一种则是从当前域名|IP|主机后的端口号开始的,不能跨域,也属于一 种绝对路径。
* 相对路径
相对路径则就是相对当前资源所在路径。
* 总结:
请求转发:
带"/"的绝对路径,定位的位置是在站点名之后
重定向:
带"/"的绝对路径,定位的位置是在端口之后

http://loaclhsot:8080/s01/ser01
注:ser01和ser02s是两个同级的servlet
相对路径
    相对于的当前资源所在路径     ser02(重定向)      ser02(请求转发)
绝对路径
    完整路径
        1、以http://开头的路径,已经跨域,可以访问任意地址   
        http://loaclhsot:8080/s01/ser02 (重定向)  (请求转发不可以)
        2、以/开头,定位在端口之后      
         /s01/ser02(重定向)         
         /ser02(在请求转发时,"/"代表的含义是从http开始到站点名后)

你可能感兴趣的:(Servlet)