【详解Servlet-3】

 之所以所HttpServlet要比GenericServlet强大,其实也是有道理的。HttpServlet是由GenericServlet抽象类扩展而来的,HttpServlet抽象类的声明如下所示:

public abstract class HttpServlet extends GenericServlet implements Serializable 

HttpServlet之所以运用广泛的另一个原因是现在大部分的应用程序都要与HTTP结合起来使用。这意味着我们可以利用HTTP的特性完成更多更强大的任务。Javax.servlet.http包是Servlet API中的第二个包,其中包含了用于编写Servlet应用程序的类和接口。Javax.servlet.http中的许多类型都覆盖了Javax.servlet中的类型。

 

一、HttpServlet抽象类

HttpServlet抽象类是继承于GenericServlet抽象类而来的。使用HttpServlet抽象类时,还需要借助分别代表Servlet请求和Servlet响应的HttpServletRequest和HttpServletResponse对象。HttpServletRequest接口扩展于javax.servlet.ServletRequest接口,HttpServletResponse接口扩展于javax.servlet.servletResponse接口。
 

public interface HttpServletRequest extends ServletRequest

public interface HttpServletResponse extends ServletResponse

 HttpServlet抽象类覆盖了GenericServlet抽象类中的Service( )方法,并且添加了一个自己独有的Service(HttpServletRequest request,HttpServletResponse方法。

让我们来具体的看一看HttpServlet抽象类是如何实现自己的service方法吧

(1) 首先来看GenericServlet抽象类中是如何定义service方法的

public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

(2)我们看到是一个抽象方法,也就是HttpServlet要自己去实现这个service方法,我们在看看HttpServlet是怎么覆盖这个service方法的

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    HttpServletRequest request;
    HttpServletResponse response;
    try {
        request = (HttpServletRequest)req;
        response = (HttpServletResponse)res;
    } catch (ClassCastException var6) {
        throw new ServletException("non-HTTP request or response");
    }
 
    this.service(request, response);
}

我们发现,HttpServlet中的service方法把接收到的ServletRequsest类型的对象转换成了HttpServletRequest类型的对象,把ServletResponse类型的对象转换成了HttpServletResponse类型的对象。之所以能够这样强制的转换,是因为在调用Servlet的Service方法时,Servlet容器总会传入一个HttpServletRequest对象和HttpServletResponse对象,预备使用HTTP。因此,转换类型当然不会出错了。

(3)转换之后,service方法把两个转换后的对象传入了另一个service方法,那么我们再来看看这个方法是如何实现的:
 

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
    long lastModified;
    if (method.equals("GET")) {
        lastModified = this.getLastModified(req);
        if (lastModified == -1L) {
            this.doGet(req, resp);
        } else {
            long ifModifiedSince = req.getDateHeader("If-Modified-Since");
            if (ifModifiedSince < lastModified) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
    } else if (method.equals("HEAD")) {
        lastModified = this.getLastModified(req);
        this.maybeSetLastModified(resp, lastModified);
        this.doHead(req, resp);
    } else if (method.equals("POST")) {
        this.doPost(req, resp);
    } else if (method.equals("PUT")) {
        this.doPut(req, resp);
    } else if (method.equals("DELETE")) {
        this.doDelete(req, resp);
    } else if (method.equals("OPTIONS")) {
        this.doOptions(req, resp);
    } else if (method.equals("TRACE")) {
        this.doTrace(req, resp);
    } else {
        String errMsg = lStrings.getString("http.method_not_implemented");
        Object[] errArgs = new Object[]{method};
        errMsg = MessageFormat.format(errMsg, errArgs);
        resp.sendError(501, errMsg);
    }
 
}

(4)接下来我们再看看service方法是如何工作的

        我们会发现在service方法中还是没有任何的服务逻辑,但是却在解析HttpServletRequest中的方法参数,并调用以下方法之一:doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete。这7种方法中,每一种方法都表示一个Http方法。doGet和doPost是最常用的。所以,如果我们需要实现具体的服务逻辑,不再需要覆盖service方法了,只需要覆盖doGet或者doPost就好了。

总结

(1)不用覆盖service方法,而是覆盖doGet或者doPost方法。在少数情况,还会覆盖其他的5个方法。

(2)使用的是HttpServletRequest和HttpServletResponse对象。

 

二、HttpServletRequest接口

HttpServletRequest表示Http环境中的Servlet请求。它扩展于javax.servlet.ServletRequest接口,并添加了几个方法。

String getContextPath();//返回请求上下文的请求URI部分

String getHeader(String var1);//返回指定HTTP标题的值

String getMethod();//返回生成这个请求HTTP的方法名称

String getQueryString();//返回请求URL中的查询字符串

HttpSession getSession();//返回与这个请求相关的会话对象

Cookie[] getCookies();//返回一个cookie对象数组

-------父类继承下来的方法--------

int getContentLength();//返回请求主体的字节数
 
String getContentType();//返回主体的MIME类型
 
String getParameter(String var1);//返回请求参数的值


--------常用的方法-------------
String getContextPath();
String getMethod();
String getQueryString();
String getParameter(String var1);
HttpSession getSession();
Cookie[] getCookies();

 

1. 通过request获得请求行

假设查询字符串为:username=zhangsan&password=123

获得客户端的请求方式:String getMethod()

获得请求的资源:

String getRequestURI()

StringBuffer getRequestURL()

String getContextPath() ---web应用的名称

String getQueryString() ---- get提交url地址后的参数字符串
 

2. 通过request获得请求头

long getDateHeader(String name)

String getHeader(String name)

Enumeration getHeaderNames()

Enumeration getHeaders(String name)

int getIntHeader(String name)

referer头的作用:执行该此访问的的来源,做防盗链
 

3. 通过request获得请求体

请求体中的内容是通过post提交的请求参数,格式是:

username=zhangsan&password=123&hobby=football&hobby=basketball

key ---------------------- value

username                               [zhangsan]

password                               [123]

hobby                                          [football,basketball]                                       

以上面参数为例,通过一下方法获得请求参数:

String getParameter(String name)

String[] getParameterValues(String name)

Enumeration getParameterNames()

Map<String,String[]> getParameterMap()

【注意】get请求方式的请求参数 上述的方法一样可以获得。

 

4. Request乱码问题的解决方法


在前面我们讲过,在service中使用的编码解码方式默认为:ISO-8859-1编码,但此编码并不支持中文,因此会出现乱码问题,所以我们需要手动修改编码方式为UTF-8编码,才能解决中文乱码问题。

(1)解决post提交方式的乱码:request.setCharacterEncoding("UTF-8");

(2)解决get提交的方式的乱码:parameter = newString(parameter.getbytes("iso8859-1"),"utf-8");

 

三、HttpServletResponse接口

在Service API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于HTTP请求消息分为状态行响应消息头响应消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法。
 

1. response常用方法 

-------add添加-------

addCookie(Cookie var1);//给这个响应添加一个cookie
addHeader(String var1, String var2);//给这个请求添加一个响应头
addIntHeader(String name, int value)
addDateHeader(String name, long date)

--------set设置-------

setHeader(String name, String value)
setDateHeader(String name, long date)
setIntHeader(String name, int value)

void setStatus(int var1);//设置响应行的状态码

void sendRedirect(String var1) throws IOException;//将浏览器跳转到指定的位置(重定向)

-------常用的方法--------
addCookie(Cookie var1);
addHeader(String var1, String var2);
setHeader(String name, String value);
void sendRedirect(String var1) throws IOException;

【提示】转发:request.getRequestDispatcher("new.jsp").forward(request, response);//转发到new.jsp

2. Response的乱码问题

方式一:

//设置response按照utf-8编码
response.setCharacterEncoding("utf-8");
//通知浏览器按照utf-8解码
response.setHeader("Content-Type","text/html;charset=utf-8");

方式二:

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

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值