zoukankan      html  css  js  c++  java
  • Java——Servlet

    一、什么是Servlet

    servlet是java ee最早提出的web组件模型。Servlet只能运行在java ee的web容器中。

    二、Servlet工作流程

    1、初始化

    每个servlet都对应一个url地址。当Web容器接受对url地址的请求信息后,根据url地址与servlet之间的映射关系将请求转发到指定的servlet来处理。如果该Web容器不存在此servlet的实例,web容器将动态装入并实例化servlet。

    2、请求处理

    针对客户端的请求,web容器将产生一个新的线程来调用servlet的service() 方法。service() 方法检查http请求类型(GETPOSTPUTDELETE等),然后调用相应的doGet()doPost()doPut()doDelete()等方法。最常见的请求类型是GET和POST。二者区别是:如果以GET请求方式传输,请求参数会直接附加在请求的url上;如果以POST请求方式传输,则参数会被打包在数据包中传送给服务器。

    注意:一个servlet同时只有一个实例,并且它在servlet的使用期间将一直保留。当有多个请求发送到同一个servlet时,服务器将会为每个请求创建一个新的线程来处理客户端的请求。

    3、退出

    当处理完客户端请求后,servlet的实例并不会立即被web容器销毁。只有web应用程序关闭或servlet已经空闲很长时间,web容器才会将servlet视力从内存移除。移除之前web容器会调用servlet的destroy() 方法。

    servlet可以使用这个方法关闭数据库连接、中断后台线程、向磁盘写入Cookie列表及执行其他清理动作。注:若web容器出现意外而被关闭,则无法保证destroy()方法被调用。

    从上面servlet工作流可以看出,客户端和servlet并没有直接交互,无论客户机对servlet的请求还是servlet对客户端的相应,都是通过web容器来实现的,这确保了servlet组件的可移植性。

    web容器的职责归纳为:

    1. 管理servlet组件的生命周期,负责servlet组建的初始化、销毁等;
    2. 将请求映射到对应的servlet,并将生成的响应返回给指定的 客户端。

    Servlet的工作流充分体现了java ee“组件-容器”的核心编程思想。

    三、Servlet API

    • HttpServlet:基于web的servlet组件通常继承此接口,完成对客户端请求的处理。
    • HttpServletRequest:代表发送到servlet组件的请求。
    • HttpServletResponse:代表从servlet组件返回客户机的响应。
    • HttpSession:代表在web应用运行过程中用来保存特定客户端状态信息的空间。
    • ServletContext:代表servlet组件的运行环境信息。
    • ServletConfig:代表servlet组件的配置信息。
    • ServletException:代表servlet组件运行过程中抛出的意外对象。
    • RequestDispatcher:请求转发器,可以将客户端请求从一个servlet转发到另外其他的服务器资源如其他servlet、静态html页面等。

    四、第一个Servlet

    编写servlet组件:

    1. 创建一个实现javax.servlet.http.HttpServlet接口的类。
    2. 重写doGet() 或doPost()方法,实现对HTTP请求信息的动态响应。

    自Java EE5 规范以后,可使用注解代替复杂的配置文件。 

    下面是个例子:

    @WebServlet("/servlet-first")
    public class Servlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    	
    	protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		response.setContentType("text/html;charest=UTF-8");
    		PrintWriter out = response.getWriter();
    		out.println("<html>");
    		out.println("<head>");
    		out.println("<title>Servlet First</title>");
    		out.println("</head>");
    		out.println("<body>");
    		out.println("<h1>Hello! This is first Servlet!</h1>");
    		out.println("</body>");
    		out.println("</html>");
    		out.close();		
    	}
       
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		processRequest(request, response);
    	}
    
    	
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		processRequest(request, response);
    	}
    
    }
    

    运行tomcat,浏览器打开输入”http://localhost:8080/ServletDemo/servlet-first“即可。

    注:在类前定义一个注解@WebServlet,它包含两个属性name和URLPattern,分别用来定义servlet组件的名称和URL模式。当部署此组件时,web容器会根据此注解自动完成对此servlet组件的部署配置。使用注解@WebServlet,需引用javax.servlet.annotation.WebServlet。

    五、处理请求

    下面是个例子:

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>处理请求</title>
    </head>
    <body>
    <form name = "form1" method="post" action="getInf">
    	<table>
    		<tr><td>姓名</td><td><input type="text" name="name"></td></tr>
    		<tr><td>年龄</td><td><input type="text" name="age"></td></tr>
    		<tr><td>出生日期(yyyy-mm-dd)</td><td><input type="text" name="birthday"></td></tr>
    		<tr><td>爱好兴趣</td></tr><tr><td><input type="checkbox" name="checkbox1" value="阅读">阅读
    							    <input type="checkbox" name="checkbox1" value="运动">运动  
    							    <input type="checkbox" name="checkbox1" value="音乐">音乐  
    							    <input type="checkbox" name="checkbox1" value="美食">美食
    							   </td></tr>
    	</table>
    	<input type="submit" name="Submit" value="提交">
    </form>
    </body>
    </html>
    

     

    @WebServlet("/getInf")
    public class GetInf extends HttpServlet {
    	private static final long serialVersionUID = 1L;
        
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		response.setContentType("text/html;charset=UTF-8");
    		request.setCharacterEncoding("UTF-8");
    		PrintWriter out = response.getWriter();
    		try {
    			String name = request.getParameter("name");
    			String age = request.getParameter("age");
    			String dateString = request.getParameter("birthday");
    			SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd");	
    			java.util.Date birth = format.parse(dateString);
    			String[] paraValues = request.getParameterValues("checkbox1");
    			String hobbies = new String("");
    			for(int i =0; i<paraValues.length;i++){
    				hobbies += paraValues[i]+"";
    			}
    			out.println("<html>");
    			out.println("<head>");
    			out.println("<title>Servlet GetInf</title>");
    			out.println("</head>");
    			out.println("<body>");
    			out.println("<h1>姓名"+ name +"</h1>");
    			out.println("<h1>年龄"+ age +"</h1>");
    			out.println("<h1>出生日期"+ birth +"</h1>");
    			out.println("<h1>爱好"+ hobbies +"</h1>");		
    			out.println("</body>");
    			out.println("</html>");
    		} catch (ParseException e) {
    			e.printStackTrace();
    		} finally{
    			out.close();
    		}
    		
    	}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }
    

    六、使用Filter过滤请求

    除了利用servlet组件直接处理客户端请求外,java ee还提供一个组件来实现对请求信息的过滤处理,称为Filter。与servlet不同,他无法生成对客户端的响应,但filter能够拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间的交换数据。filter可以改变一个请求或者修改响应。filter与servlet的关联由web应用的配置文件或注解来明确。

    用户发送请求给servlet时,在servlet处理请求前,首先由于此servlet关联的filter执行,然后才是servlet的执行。如果一个servlet有多个filter,则根据配置的前后次序执行。

    Filter主要用于以下场景:

    • 访问特定资源(web、jsp、servlet)时验证身份。
    • 访问资源的记录跟踪。
    • 访问资源的转换。

    一个Filter必须实现javax.servlet.Filter接口,即实现以下三个方法:

    1. doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 。用来实现过滤行为的方法。引入的FilterChain对象提供了后续Filter所要调用的信息。
    2. init(FilterConfig fConfig)。由容器所调用的Filter出师方法。
    3. destroy() 。

    下面是个例子:

    @WebFilter(filterName="/IPFilter", urlPatterns={"/*"})
    public class IPFilter implements Filter {
    
    	private FilterConfig fConfig = null;
    
    	public void destroy() {
    		this.fConfig  = null;
    	}
    
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    		String ipAddress = request.getRemoteAddr();
    		System.out.println("IP" + ipAddress +", Time" + new Date().toString());
    		chain.doFilter(request, response);
    	}
    
    	public void init(FilterConfig fConfig) throws ServletException {
    		this.fConfig  = fConfig;
    	}
    
    }
    

     注:

      过滤器有两种映射模式:

    •   对URL模式的映射,这也是默认的映射模式。在URL模式中可以试用通配符,如"/*"。
    •   对servlet的映射。这时过滤器关联的是servlet的逻辑名称。

    与servlet一样,新版本的java ee规范中,提供了注解@WebFilter来部署Filter组件,其属性filterName为Filter的逻辑名称, 属性urlPatterns为Filter的URL模式。

    程序包含了Filter必须实现的三个接口方法:init()、destroy()和doFilter()。当容器第一次加载该过滤器时,init()方法被调用。该类这个方法包含了一个指向FilterConfig对象的引用。对请求和响应的过滤功能主要由doFilter()实现。web容器在垃圾收集之前调用destroy()方法,以便能够执行任何必须清理的代码。

  • 相关阅读:
    (兼容IE8)的渐变
    左侧固定,右侧自适应,两列等高并且自适应的第二种办法
    左侧定宽,右侧自适应,两列布局且等高
    下拉框重写
    在页面中输出当前客户端时间
    用哈希表去数组重复项,有详细注释
    求数组最大值、求和、乘法表、取整
    类似新浪微博输入字符计数的效果
    将博客搬至CSDN
    Mysql常用操作
  • 原文地址:https://www.cnblogs.com/iCcccy/p/4829439.html
Copyright © 2011-2022 走看看