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

 

http://localhost:8080/test15/TomcatTest/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>

posted @ 2017-04-02 11:56  jhtchina  阅读(171)  评论(0)    收藏  举报