您的位置:首页 > 理论基础 > 计算机网络

Java Web基础知识之Servlet(2):深入Servlet——HttpServlet

2017-08-24 16:46 274 查看

一、 Servlet的继承结构

Servlet其实只有一个直接实现类和一个间接实现类,如下:



其实Servlet并不是只可以服务于Http协议,它可以按照很多协议进行通信,但是目前实现的只有http协议,但是不能把Servlet等同于只是服务于Http协议的Servlet。
我们之前创建自己的Servlet时,都是直接实现Servlet接口,但是这样就有一个问题,每次都要把所有的方法都要实现一遍,这样在业务上并没有必要,我们只是专注于接收请求并返回响应,其他的方法不是很关注。通过继承GenericServlet我们就可以专注于对请求的处理,而将生命周期方法和其他参数都交给GenericServlet来处理,这样大大简化了我们的开发工作。
GenericServlet是一个抽象类,它里面其实就是将Servlet的周期方法封装起来或者给出了一个空实现,另外还有就是将ServletConfig和ServletContext类的一些方法和获取实例的方法封装了一下,在里面我们最值得注意的是init()方法的使用。在这个类中,有两个init()方法,一个是对Servlet接口的实现,一个是自定义的init(){},一个空实现,这就给我们实现这个方法造成了一些困惑,应该继承哪个?由于我们通过该类的实例来获得ServletConfig的实例,如果没有处理好init(),则会造成ServletConfig为空,看GenericServlet中的init()方法,如下:
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {}
可以看出在init(ServletConfig config)中调用了init()方法,所以我们在继承GenericServlet时可以这样处理:

不实现init(ServletConfig config)方法,这样所有的初始化工作都由GenericServlet来实现;
实现init()方法来进行我们的初始化工作,这样在GenericServlet的init(ServletConfig config)被Servlet容器调用的时候,我们自己的init()也会被调用;
实现init(ServletConfig config) 方法,但在Servlet容器调用它的时候,我们也可以通过super.init(config)来调用GenericServlet的init(ServletConfig config)方法来完成资源的初始化;

二、 直接使用HttpServlet

终于来到我们的重点了,我们编写所有的web程序实际上都是在应用HttpServlet,因为我们的Web程序都是通过http进行通信的,所以说直接使用HttpServlet更直接,相对于GenericServlet使用HttpServlet不用再统一的使用service()来处理请求了,而是将对不同的Http方法来处理请求。这个类里边主要是实现了对不同Http的方法处理,处理方式主要是通过新建一个service()方法,接收生命周期方法servcie()的转发,如下:
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest  request;
HttpServletResponse response;

if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}

request = (HttpServletRequest) req;
response = (HttpServletResponse) res;

service(request, response);
}
调用自己新建的service(HttpServletRequest req, HttpServletResponse resp)方法来对Http协议进行支持。对Http的支持无非就是对get、post等请求进行处理,然后返回响应。
所以我们先将4个与请求、响应有关的类介绍一下。
首先是ServletReques和ServletResponse类,它们在Servlet容器调用service()方法前由容器创建并传递给该方法。
ServletRequest接口的方法:
获取请求参数:
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service");

System.out.println(req.getParameter("user"));
System.out.println("------------");
System.out.println(Arrays.asList(req.getParameterValues("shop")));
System.out.println("------------");
Map<String, String[]> params = req.getParameterMap();
for(String key: params.keySet()){
System.out.println(key + "=" + Arrays.asList(params.get(key)));
}
System.out.println("------------");
Enumeration<String> enums = req.getParameterNames();
while(enums.hasMoreElements()){
String paramName = enums.nextElement();
String paramValue = req.getParameter(paramName);
System.out.println(paramName + "=" + paramValue);
}
}
输入如下:



从输出可以看出最后一个方法getParameterNames()返回参数值时没如果参数是一个数组,该方法只会返回参数的第一个值。
ServletRequest的子接口HttpServletRequest有很多针对Http协议的处理请求的方法,方法太多就不介绍了。
ServletResponse接口的方法:里面有一些简单的方法,比如设置编码方式、内容大小、还有一些国际化需要的东西,另外最有用的就是获取OutputStream和Writer来输出数据。
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service");
res.setContentType("application/msword");
res.getWriter().write("from servlet service method");
}
上面的代码设置了返回值类型是一个word文档并写入数据。
ServletResponse的一个子接口HttpServletResponse中也有很多的方法,后面使用到具体的内容,比如说cookie和session时会进行介绍,这里就不一一介绍,如果需要直接查看API文档即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tomcat servlet web应用