Servlet简e介、原理以及封装
Q1:servlet简介
Servlet是sun公司提供的一门用于开发动态web资源的技术。
Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
1、编写一个Java类,实现servlet接口。
2、把开发好的Java类部署到web服务器中。
按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet
Q2:Servlet生命周期与原理
1、Servlet 生命周期:Servlet 加载--->实例化--->服务--->销毁。
2、init():在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问 Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。
3、service():它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求” (ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。
4、destroy(): 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会 产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。
图片给予详细说明:
如上图所示,我们来给予一个详细说明,首先:客户端发送get请求到web服务器(apache),再发送get请求到web容器,再发送get请求到servlet,在servle中,首先看看
是否有Servlet实例,如果没有,就先创建Servlet实例,如果有,就直接调用init(),service();destroy();等方法。最后再按原路进行相应,直到客户端。。。
Q3:Servlet封装
下面有我对Servlet的一些内容的封装,现在做项目,大多用到Servlet,如果每有一个Servlet,便去给他写里面重复的内容,便会很麻烦,有了下面的封装,代码会变的比较简单。
封装Servlet(BaseController)
package actions; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/BaseController") public class BaseController extends HttpServlet { private static final long serialVersionUID = 1L; public BaseController() { super(); } protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String action=request.getParameter("action"); if(action!=null) { //在当前Servlet实例中根据action找到方法信息 try { Method method = getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class); if (method != null) { // 在当前实例上调用方法method,指定参数request,response try { method.invoke(this, request, response); } catch (IllegalAccessException e) { // TODO Auto-generated catch block System.out.println("安全权限异常,一般来说,是由于java在反射时调用了private方法所导致的。如" + "果是这种情况的话,要把反射pirvate的方向设置成public,再调用"); //e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block System.out.println("此异常表明向方法传递了一个不合法或不正确的参数"); //e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block System.out.println("是一种包装由调用方法或构造方法所抛出异常的受查异常"); //e.printStackTrace(); } } } catch (NoSuchMethodException e) { // TODO Auto-generated catch block response.getWriter().write("您请求的action不存在"); //e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block System.out.println("是安全异常的意思。你再仔细检查和安全设置相关的选项是否都设置正确。"); //e.printStackTrace(); } }else { response.getWriter().write("请指定参数action。"); } } }
提示:这个Servlet中结合了反射,没有理解反射的可以先好好理解一下。。
现在,我们来写一个使用的Servlet
package action; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import actions.BaseController; @WebServlet("/UserController") public class UserController extends BaseController { private static final long serialVersionUID = 1L; /**添加*/ public void add(HttpServletRequest request, HttpServletResponse response) { System.out.println("执行添加"); } /**删除*/ public void delete(HttpServletRequest request, HttpServletResponse response) { System.out.println("执行删除"); } }
从上面可以看出,我们这个Servlet继承了上面的Servlet,也使得Servlet变得简单了
结果:
这是我们还没有指定参数
指定添加
服务器中不存在这个方法