Servlet的继承体系与HttpServletRequset和HttpServletResponse

一、Servlet的继承体系与分析

     如果每一个自定义的Servlet类都 implements Servlet接口,那么多个Servelt中就会出现重复代码。

     解决方案:重构代码,消除重复

1、GenericServlet 抽象类 implements Servlet, ServletConfig, java.io.Serializable

     GenericServlet类可以处理普通的请求和响应

     1)Servlet的 init(config)方法,并在该方法中编写自己的初始化代码

          GenericServlet类专门提供了一个无参数的初始化方法 init(),暴露给子类去实现。

       

执行步骤:

       当执行 GenericServlet的 init(config)方法时,会调用this.init()方法(多态的作用),会执行子类实现的方法,

     2)定义一个全局的 ServletConfig对象

         把当前的servletConfig对象暴漏给子类访问使用,并覆写了ServletConfig的操作方法

         遵循守恒原则,子类就少写了代码  那么父类要给补回来 。

         

     3)service方法定义成抽象的,让子类必须实现,所以GenericServlet类也是抽象的

         

   

  自定义Servlet类继承GenericServlet

public class LifeServlet extends GenericServlet {
    private static final long serialVersionUID = 1L;
    
    private ServletContext servletContext;
    
    @Override
    public void init() throws ServletException {
       System.out.println("init");
    }
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("service");
        ServletConfig config = getServletConfig();
        servletContext = getServletContext();
        System.out.println(config);
        System.out.println(servletContext);
        
        Enumeration enumeration = getInitParameterNames();
        while (enumeration.hasMoreElements()) {
            String name = (String) enumeration.nextElement();
            String value = getInitParameter(name);
            System.out.println(name + ";" + value);
        }        
    }   
    
}

    

 

如何处理HTTP类型的请求和响应

2、HttpServlet抽象类 extends GenericServlet

     HttpServlet类可以处理 HTTP协议的请求和响应。

     http请求有GET、POST请求,针对不同的请求,分而治之。解决方案:提供doGet方法与doPost方法

    1)service方法获取http信息,分而治之

       

    2)分而治之的doXxx方法需子类去实现

        

   

自定义Servlet类继承HttpServlet

public class LifeServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    private ServletContext servletContext;
    
    @Override
    public void init() throws ServletException {
       System.out.println("init");
    }
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPut(req, resp);
    }
    
    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service");
        ServletConfig config = getServletConfig();
        servletContext = getServletContext();
        System.out.println(config);
        System.out.println(servletContext);
        
        Enumeration enumeration = getInitParameterNames();
        while (enumeration.hasMoreElements()) {
            String name = (String) enumeration.nextElement();
            String value = getInitParameter(name);
            System.out.println(name + ";" + value);
        }        
    } 
}

开发中一般的Servlet继承体系:

       

 

API文档https://docs.oracle.com/javaee/7/api/

二、HttpServletRequset接口     

       在Servlet API中,ServletRequest接口被定义为用于封装请求的信息,ServletRequest对象由Servlet容器在用户请求Servlet时创建并传入Servlet的service()方法中。

      HttpServletRequest接口继承了ServletRequest接口,是专用于HTTP协议的子接口,用于封装HTTP请求信息。在HttpServlet类的service()方法中,传入的ServletRequest对象被强制转换为HttpServletRequest对象来进行HTTP请求信息的处理。

1、HttpServletRequset中常用方法:具体查看API

     1)获取请求行信息

getMethod():获取请求使用的HTTP方法,如POST,GET
getRequestURI():获取请求行中的资源名部分
getProtocol():获取使用的协议及版本号,如HTTP/1.1
getQueryString():获取请求URL后面的查询字符串,只对GET有效
getServletPath():获取Servlet所映射的路径
getContextPath():获取请求资源所属于的web应用的路径

     2)获取请求头信息

getIntHeader(String name):获取整数类型参数名为name的http头部
getDateHeader(String name):获取long类型参数名为name的http头部
getContextLength():获取请求内容的长度,以字节为单位
getContextType():获取请求的文档类型和编码
getLocale():获得用户浏览器设置的Locale信息
getCookies():获取一个Cookie[]数组,该数组包含这个请求中当前的所有cookie

常见请求头:    

     3)获取请求正文

        请求正文内容为POST请求参数名称和值组成的一个字符串。POST请求主要通过form表单进行数据提交,而<form>表单元素的enctype属性可以指定两种编码方式,默认使用的是application/x-www-form-urlencoded。在这种情况下,浏览器提交表单的时候会将元素名和元素值以“=”分隔形成一个参数,每个参数之间以&分隔组成正文内容。

       在Servlet中可以使用:getParameter(String name),getParameterNames(),getParameterValues(String name),getParametrerMap()等方法获取参数名和参数值。

       当表单想服务器上传文件时enctype使用的是multipart/form-data。其编码方式的请求正文由描述头、空行和主体内容三部分组成,非文件类型元素的主体内容就是表单设置的值,文件类型的主体内容文文件的二进制数据形式。

       在Servlet中可以使用:getInputStream(),getReader等方法进行获取。同时@MultiPartConfig注解方式也有方法提供。

      4)获取网络连接信息

getRemoteAddr():获取请求用户的ip地址
getRemoteHost():获取请求用户的主机名
getRemotePort():获取请求用户使用的端口号
getLocalAddr():获取web服务器的ip地址
getLocalName():获取web服务器的主机名
getLocarPort():获取web服务器使用的端口号
getServerName():获取网站的域名
getServerPort():获取url请求的端口号
getScheme():获取请求使用的协议
getRequestURL:获取请求的url地址

     5)存取请求域属性

void setAttribute(String name, Object value):设定name的属性值为value,保存在request范围内
Object getAttribute(String name):从request范围了获取name属性的值
void removeAttribute(String name):从request范围移除name属性的值
Enumeration getAttributeNames():获取所有request范围的属性

三、HttpServletResponse接口

     ServletResponse接口:该对象封装了服务器要返回客户端的所有响应信息。如果使用HTTP,则包含了HTTP的响应行、响应头部和响应体。

     HttpServletResponse接口:是ServletResponse的子接口,处理HTTP协议响应信息。

1、HttpServletResponse中常用方法:具体查看API

    1)设置返回内容类型

        response.setContentType("text/html");

     response.setContentType(MIME)的作用是使客户端浏览器,区分不同种类的数据,并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。

    2)设置字符编码

        response.setCharacterEncoding("UTF-8");

    3)设置响应状态码

        response.setStatus(200);

    4)设置响应头

        response.setHeader("username", "admin");//也可以添加一些私人的头部信息

    5)发送返回内容

  response.getWriter().writer();   发送字符实体内容

  response.getOutputStream().writer()  发送字节实体内容,比如文件下载等

       注意:这两个方法不能共存,会报错。

    6)设置输出的内容的MIME类型    

voidsetContentType(String type)

Sets the content type of the response being sent to the client, if the response has not been committed yet.

    三、四的一个简单demo

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        String username = req.getParameter("username") ;
        String password = req.getParameter("password") ;        
        
        /* 
        resp.setContentType("text/html"); // 设置输出的MIME类型(内容的类型)
        resp.setCharacterEncoding("UTF-8"); // 设置输出数据的编码方式
        */
        //推荐使用此方法。等同于上面两行代码
        resp.setContentType("text/html;charset=utf-8");
        
        PrintWriter out = resp.getWriter();
        out.write("<html><head><title>this is tilte</title></head><body>");
        out.write("LifeServlet:" + username + "--" + password);
        out.write("</body></html>");
    }

浏览器方法:http://127.0.0.1:8080/DemoServlet/life?username=admin&password=123456

   

   

 

三、请求的中文乱码问题

       在Tomcat中,对于POST和GET请求,都默认采用 ISO-8859-1的编码方式,而 ISO-8859-1不支持中文,所以乱码

1、解决方案(不推荐)

     按照 ISO-8859-1 把乱码恢复成二进制形式的数据,然后再把二进制形式的数据使用UTF-8重新编码。

        byte[] usernamedata = username.getBytes("ISO-8859-1");
        username = new String(usernamedata, "UTF-8");
        System.out.println(username);

2、解决方案(推荐)

    1)针对POST请求方法        

        req.setCharacterEncoding("UTF-8");

        注意:必须放在获取任意参数之前,对GET无效

    2)针对GET请求方法

         修改Tomcat中的server.xml配置文件,如下:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

参考文章:

    HttpServletRequset接口相关内容全解

    HttpServletResponse接口详解

 

    站在前辈的肩膀上,每天进步一点点

ends~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值