servlet技术
Servlet 技术
(1) Servlet 生命周期
A 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
B Servlet 容器在调用 service() 方法之前加载 Servlet。
C 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。
(2) Servlet 实例
(3) Servlet 表单数据
A http://localhost:8080/test15/HelloForm?name=%E8%8F%9C%E9%B8%9F%E6%95%99%E7%A8%8B&url=www.runoob.com
B
Servlet 处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析:
getParameter():您可以调用 request.getParameter() 方法来获取表单参数的值。
getParameterValues():如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框。
getParameterNames():如果您想要得到当前请求中的所有参数的完整列表,则调用该方法。
C
下面是处理 Web 浏览器输入的 HelloForm.java Servlet 程序。我们将使用 getParameter() 方法,可以很容易地访问传递的信息:
| package com.runoob.test; 
 import java.io.IOException; import java.io.PrintWriter; 
 import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 
 /** * Servlet implementation class HelloForm */ @WebServlet("/HelloForm") public class HelloForm extends HttpServlet { private static final long serialVersionUID = 1L; 
 /** * @see HttpServlet#HttpServlet() */ public HelloForm() { super(); // TODO Auto-generated constructor stub } 
 /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置响应内容类型 response.setContentType("text/html;charset=UTF-8"); 
 PrintWriter out = response.getWriter(); String title = "使用 GET 方法读取表单数据"; // 处理中文 String name =new String(request.getParameter("name").getBytes("ISO8859-1"),"UTF-8"); String docType = "<!DOCTYPE html> \n"; out.println(docType + "<html>\n" + "<head><title>" + title + "</title></head>\n" + "<body bgcolor=\"#f0f0f0\">\n" + "<h1 align=\"center\">" + title + "</h1>\n" + "<ul>\n" + " <li><b>站点名</b>:" + name + "\n" + " <li><b>网址</b>:" + request.getParameter("url") + "\n" + "</ul>\n" + "</body></html>"); } 
 // 处理 POST 方法请求的方法 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } 
 } | 
D然后我们在 web.xml 文件中创建以下条目:
| <web-app> <servlet> <servlet-name>HelloForm</servlet-name> <servlet-class>com.runoob.test.HelloForm</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloForm</servlet-name> <url-pattern>/TomcatTest/HelloForm</url-pattern> </servlet-mapping> </web-app> | 
E
(4) Servlet 编写过滤器
过滤器(Filter)的概念
1过滤器位于客户端和web应用程序之间,用于检查和修改两者之间流过的请求和响应。
2在请求到达Servlet/JSP之前,过滤器截获请求。
3在响应送给客户端之前,过滤器截获响应。
4多个过滤器形成一个过滤器链,过滤器链中不同过滤器的先后顺序由部署文件web.xml中过滤器映射<filter-mapping>的顺序决定。
5最先截获客户端请求的过滤器将最后截获Servlet/JSP的响应信息。
过滤器的链式结构
可以为一个Web应用组件部署多个过滤器,这些过滤器组成一个过滤器链,每个过滤器只执行某个特定的操作或者检查。这样请求在到达被访问的目标之前,需要经过这个过滤器链。
实现过滤器(以过滤非法字符为例)
在Web应用中使用过滤器需要实现javax.servlet.Filter接口,实现Filter接口中所定义的方法,并在web.xml中部署过滤器。
1 创建类WordFilter,实现Filter接口
| import java.io.IOException; 
 import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; 
 /** * 非法字符过滤器 * @author Li Yong Qiang */ public class WordFilter implements Filter { // 非法字符数组 private String words[]; // 字符编码 private String encoding; // 实现Filter接口init()方法 @Override public void init(FilterConfig filterConfig) throws ServletException { // 获取字符编码 encoding = filterConfig.getInitParameter("encoding"); // 初始化非法字符数组 words = new String[]{"糟糕","混蛋"}; } // 实现Filter接口doFilter()方法 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 判断字符编码是否有效 if (encoding != null) { // 设置request字符编码 request.setCharacterEncoding(encoding); // 将request转换为重写后的Request对象 request = new Request((HttpServletRequest) request); // 设置response字符编码 response.setContentType("text/html; charset="+encoding); } chain.doFilter(request, response); } // 实现Filter接口destroy()方法 @Override public void destroy() { this.words = null; this.encoding = null; } /** * 内部类重写HttpServletRequestWrapper * @author Li Yong Qiang */ class Request extends HttpServletRequestWrapper{ // 构造方法 public Request(HttpServletRequest request) { super(request); } // 重写getParameter()方法 @Override public String getParameter(String name) { // 返回过滤后的参数值 return filter(super.getRequest().getParameter(name)); } // 重写getParameterValues()方法 @Override public String[] getParameterValues(String name) { // 获取所有参数值 String[] values = super.getRequest().getParameterValues(name); // 通过循环对所有参数值进行过滤 for (int i = 0; i < values.length; i++) { values[i] = filter(values[i]); } // 返回过滤后的参数值 return values; } } /** * 过滤非法字符 * @param param 参数值 * @return 过滤后的参数值 */ public String filter(String param){ try { // 判断非法字符是否被初始化 if(words != null && words.length > 0){ // 循环替换非法字符 for (int i = 0; i < words.length; i++) { // 判断是否包含非法字符 if(param.indexOf(words[i]) != -1){ // 将非法字符替换为"****" param = param.replaceAll(words[i], "****"); } } } } catch (Exception e) { e.printStackTrace(); } return param; } } | 
2 创建HttpServlet对象的MessageServlet 类
| /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //doGet(request, response); // 获取标题 String title = request.getParameter("title"); // 获取内容 String content = request.getParameter("content"); // 将标题放置到request中 request.setAttribute("title", title); // 将内容放置到request中 request.setAttribute("content", content); // 转发到result.jsp页面 request.getRequestDispatcher("index.jsp").forward(request, response); } | 
3 对web.xml进行配置
| <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- Servlet配置 --> <servlet> <servlet-name>MessageServlet</servlet-name> <servlet-class>com.lyq.MessageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MessageServlet</servlet-name> <url-pattern>/test123/MessageServlet</url-pattern> </servlet-mapping> <!-- 过滤器配置 --> <filter> <filter-name>WordFilter</filter-name> <filter-class>com.lyq.WordFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>WordFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 主页面 --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> | 
4 创建index.jsp
| <% String title = (String)request.getAttribute("title"); String content = (String)request.getAttribute("content"); if(title != null && !title.isEmpty()){ out.println("<span class='tl'>" + title + "</span>"); } if(content != null && !content.isEmpty()){ out.println("<span class='ct'>" + content + "</span>"); } %> <span class="tl">谢谢你们</span> <span class="ct">你们的公司服务态度非常好,谢谢你们!</span> <span class="tl">谢谢你们</span> <span class="ct">你们的公司服务态度非常好<br>但部分客服服务态度还要加强!</span> <form action="MessageServlet" method="post"> <span class="tt">意见反馈</span> <table border="0" width="500" align="center"> <tr> <td align="right">标 题:</td> <td><input type="text" name="title" size="30"></td> </tr> <tr> <td align="right">内 容:</td> <td> <textarea rows="5" cols="40" name="content"></textarea> </td> </tr> <tr> <td align="center" colspan="2"> <input type="submit" value="提 交"> </td> </tr> </table> </form> 
 | 
实现非法字符过滤
(5) Servlet 文件上传
Servlet 可以与 HTML form 标签一起使用,来允许用户上传文件到服务器。上传的文件可以是文本文件或图像文件或任何文档。
本文使用到的文件有:
upload.jsp : 文件上传表单。
message.jsp : 上传成功后跳转页面。
UploadServlet.java : 上传处理 Servlet。
需要引入的 jar 文件:commons-fileupload-1.3.2、commons-io-2.5.jar。
1 upload.jsp 文件代码如下:
| <body> <h1>文件上传实例 - 菜鸟教程</h1> <form method="post" action="UploadServlet" enctype="multipart/form-data"> 选择一个文件: <input type="file" name="uploadFile" /> <br/><br/> <input type="submit" value="上传" /> </form> </body> | 
2编写后台 Servlet
以下是 UploadServlet 的源代码,同于处理文件上传,在这之前我们先确保依赖包已经引入到项目的 WEB-INF/lib 目录下:
下面的实例依赖于 FileUpload,所以一定要确保在您的 classpath 中有最新版本的 commons-fileupload.x.x.jar 文件。可以从 http://commons.apache.org/proper/commons-fileupload/ 下载。
FileUpload 依赖于 Commons IO,所以一定要确保在您的 classpath 中有最新版本的 commons-io-x.x.jar 文件。可以从 http://commons.apache.org/proper/commons-io/ 下载。
UploadServlet 的源代码 如下所示:
| 
 import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.List; 
 import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 
 import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; 
 
 /** * Servlet implementation class UploadServlet */ @WebServlet("/UploadServlet") public class UploadServlet extends HttpServlet { //private static final long serialVersionUID = 1L; 
 // 上传文件存储目录 private static final String UPLOAD_DIRECTORY = "upload"; 
 // 上传配置 private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB 
 /** * 上传数据及保存文件 */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
 System.out.println("Test1"); 
 // 检测是否为多媒体上传 if (!ServletFileUpload.isMultipartContent(request)) { // 如果不是则停止 PrintWriter writer = response.getWriter(); writer.println("Error: 表单必须包含 enctype=multipart/form-data"); writer.flush(); return; } 
 // 配置上传参数 DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中 factory.setSizeThreshold(MEMORY_THRESHOLD); // 设置临时存储目录 factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); 
 ServletFileUpload upload = new ServletFileUpload(factory); 
 // 设置最大文件上传值 upload.setFileSizeMax(MAX_FILE_SIZE); 
 // 设置最大请求值 (包含文件和表单数据) upload.setSizeMax(MAX_REQUEST_SIZE); 
 // 中文处理 upload.setHeaderEncoding("UTF-8"); 
 // 构造临时路径来存储上传的文件 // 这个路径相对当前应用的目录 String uploadPath = request.getServletContext().getRealPath("./") + File.separator + UPLOAD_DIRECTORY; 
 System.out.println(uploadPath); 
 // 如果目录不存在则创建 File uploadDir = new File(uploadPath); if (!uploadDir.exists()) { uploadDir.mkdir(); } 
 try { // 解析请求的内容提取文件数据 @SuppressWarnings("unchecked") List<FileItem> formItems = upload.parseRequest(request); 
 if (formItems != null && formItems.size() > 0) { // 迭代表单数据 for (FileItem item : formItems) { // 处理不在表单中的字段 if (!item.isFormField()) { String fileName = new File(item.getName()).getName(); String filePath = uploadPath + File.separator + fileName; File storeFile = new File(filePath); // 在控制台输出文件的上传路径 System.out.println(filePath); // 保存文件到硬盘 item.write(storeFile); request.setAttribute("message", "文件上传成功!"); } } } } catch (Exception ex) { request.setAttribute("message", "错误信息: " + ex.getMessage()); } // 跳转到 message.jsp request.getServletContext().getRequestDispatcher("/message.jsp").forward( request, response); } } | 
3 message.jsp 文件代码如下:
| <body> <center> <h2>${message}</h2> </center> </body> | 
4 编译和运行 Servlet
| <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <servlet> <display-name>UploadServlet</display-name> <servlet-name>UploadServlet</servlet-name> <servlet-class>com.runoob.test.UploadServlet</servlet-class> </servlet> 
 <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/TomcatTest/UploadServlet</url-pattern> </servlet-mapping> </web-app> | 
 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号