[Servlet&JSP] 封装器的使用

简介: 过滤器可以在执行Servlet的service()方法前后,进行前置和后置处理。但是有些信息无法更改,例如请求参数。使用请求封装器及相应封装器,将容器产生的请求与相应对象加以封装,可以针对某个请求信息或响应进行加工处理。请求封装器HttpServletRequestWrapper实现了HttpServletRequest接口,以下范例通过继承HttpServlet

过滤器可以在执行Servlet的service()方法前后,进行前置和后置处理。但是有些信息无法更改,例如请求参数。使用请求封装器及相应封装器,将容器产生的请求与相应对象加以封装,可以针对某个请求信息或响应进行加工处理。

请求封装器

HttpServletRequestWrapper实现了HttpServletRequest接口,以下范例通过继承HttpServletRequestWrapper实现了一个请求封装器,可以请请求参数中的角括号替换为替代字符。

import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class CharacterRequestWrapper extends HttpServletRequestWrapper{
    private Map<String, String> escapeMap;

    public CharacterRequestWrapper(HttpServletRequest request, 
            Map<String, String> escapeMap) {
        super(request); //封装传入的请求对象
        this.escapeMap = escapeMap;
    }

    @Override
    public String getParameter(String name) { //重写getParameter()方法
        return doEscape(this.getRequest().getParameter(name));
    }

    private String doEscape(String parameter) {
        if (parameter == null) {
            return null;
        }
        String result = parameter;
        Iterator<String> it = escapeMap.keySet().iterator();
        while(it.hasNext()) {
            String origin = it.next();
            String escape = escapeMap.get(origin);
            result = result.replaceAll(origin, escape);
        }

        return result;
    }
}

可以使用这个请求封装器搭配过滤器,以进行字符过滤的服务。例如:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

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;

public class CharacterFilter implements Filter {
    private Map<String, String> escapeMap;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        BufferedReader reader = null;
        try {
            String escapeListFile = filterConfig.getInitParameter("ESCAPE_LIST");
            reader = new BufferedReader(new InputStreamReader(
                    filterConfig.getServletContext().getResourceAsStream(escapeListFile)));

            String input = null;
            escapeMap = new HashMap<String, String>();
            while ((input = reader.readLine()) != null) {
                String[] token = input.split("\t");
                escapeMap.put(token[0], token[1]);
            }
        } catch (IOException ex) {
            Logger.getLogger(CharacterFilter.class.getName())
                    .log(Level.SEVERE, null, ex);
        } finally {
            try {
                reader.close();
            } catch (IOException ex) {
                Logger.getLogger(CharacterFilter.class.getName())
                        .log(Level.SEVERE, null, ex);
            }
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        //将原请求对象封装到CharacterRequestWrapper中
        HttpServletRequest requestWrapper = 
                new CharacterRequestWrapper((HttpServletRequest)request, escapeMap);
        //将CharacterRequestWrapper对象当做请求参数传入doFilter()
        chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}

响应封装器

如果想要对响应的内容进行压缩处理等,可以在响应封装器部分继承HttpServletResponseWrapper类来对HttpServletResponse对象进行封装。

如要对浏览器进行输出响应,必须通过getWriter()取得PrintWriter,或是通过getOutputStream()取得ServletOutputStream。所以针对压缩输出的请求,主要就是继承HttpServletResponseWrapper之后,通过重写这两个方法来达成的。

在这里压缩功能将采用GZIP格式,这是浏览器可以接受的压缩格式,可以使用GZIPOutputStream类来实现。由于getWriter()的PrintWriter在创建时也是必须要用到ServletOutputStream,所以这里首先扩展ServletOutputStream类,让它具有压缩功能。

GzipServletOutputStream.java:

package club.chuxing;

import java.io.IOException;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;

public class GZipServletOutputStream extends ServletOutputStream{
    private GZIPOutputStream gzipOutputStream;

    public GZipServletOutputStream(ServletOutputStream servletOutputStream) 
            throws IOException {
        this.gzipOutputStream = new GZIPOutputStream(servletOutputStream);
    }

    public void write(int b) throws IOException {
        //输出时通过GZIPOutputSteam的write()压缩输出
        gzipOutputStream.write(b);
    }

    public GZIPOutputStream getGzipOutputStream() {
        return gzipOutputStream;
    }

    @Override
    public boolean isReady() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void setWriteListener(WriteListener listener) {
        // TODO Auto-generated method stub
    }
}

CompressionResponseWrapper.java:

package club.chuxing;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class CompressionResponseWrapper extends HttpServletResponseWrapper {
    private GZipServletOutputStream gzServletOutputStream;
    private PrintWriter printWriter;
    public CompressionResponseWrapper(HttpServletResponse resp) {
        super(resp);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if (printWriter != null) {
            throw new IllegalStateException();
        }
        if (gzServletOutputStream == null) {
            gzServletOutputStream = new GZipServletOutputStream(
                    getResponse().getOutputStream());
        }

        return gzServletOutputStream;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        if (gzServletOutputStream != null) {
            throw new IllegalStateException();
        }
        if (printWriter == null) {
            gzServletOutputStream = new GZipServletOutputStream(
                    getResponse().getOutputStream());
            OutputStreamWriter osw = new OutputStreamWriter(
                    gzServletOutputStream, getResponse().getCharacterEncoding());
            printWriter = new PrintWriter(osw);
        }

        return printWriter;
    }

    @Override
    public void setContentLength(int len) {

    }

    public GZIPOutputStream getGZIPOutputStream() {
        if (this.gzServletOutputStream == null) {
            return null;
        }
        return this.gzServletOutputStream.getGzipOutputStream();
    }
}

CompressionFilter.java(压缩过滤器):

package club.chuxing;

import java.io.IOException;
import java.util.zip.GZIPOutputStream;

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.HttpServletResponse;

public class CompressionFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse res = (HttpServletResponse)response;

        String encodings = req.getHeader("accept-encoding");
        if ((encodings != null) && encodings.indexOf("gzip") > -1) {
            //建立响应封装
            CompressionResponseWrapper responseWrapper = 
                    new CompressionResponseWrapper(res);
            //设置响应内容编码为gzip格式
            responseWrapper.setHeader("content-encoding", "gzip");

            chain.doFilter(request, responseWrapper);

            GZIPOutputStream gzipOutputStream = responseWrapper.getGZIPOutputStream();
            if (gzipOutputStream != null) {
                //调用GZIPOutputStream的finish()方法完成压缩输出
                gzipOutputStream.finish();
            }
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}

最后,将过滤器设置在web.xml中,响应就会是压缩过后的内容。

目录
相关文章
|
1月前
|
Java 容器
【学习笔记】Jsp与Servlet技术
【学习笔记】Jsp与Servlet技术
72 0
|
3月前
|
SQL Java 数据库
jsp中使用Servlet查询SQLSERVER数据库中的表的信息,并且打印在屏幕上
该博客文章介绍了在JSP应用中使用Servlet查询SQL Server数据库的表信息,并通过JavaBean封装图书信息,将查询结果展示在Web页面上的方法。
jsp中使用Servlet查询SQLSERVER数据库中的表的信息,并且打印在屏幕上
|
3月前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
Java服务器端技术:Servlet与JSP的集成与扩展
37 3
|
3月前
|
存储 缓存 前端开发
Servlet与JSP在Java Web应用中的性能调优策略
Servlet与JSP在Java Web应用中的性能调优策略
34 1
|
3月前
|
供应链 前端开发 Java
JSP+servlet+mybatis+layui服装库存管理系统(大三上学期课程设计)
这篇文章通过一个服装库存管理系统的实例,展示了在Spring Boot项目中使用Ajax、JSON、layui、MVC架构和iframe等技术,涵盖了注册登录、权限管理、用户管理、库存管理等功能,并提供了系统运行环境和技术要求的详细说明。
JSP+servlet+mybatis+layui服装库存管理系统(大三上学期课程设计)
|
3月前
|
存储 Java 关系型数据库
基于Servlet和JSP的Java Web应用开发指南
基于Servlet和JSP的Java Web应用开发指南
57 0
|
3月前
|
前端开发 安全 Java
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
29 0
|
4月前
|
XML Java 数据格式
jsp和servlet有什么区别?
总的来说,JSP和Servlet都是创建动态Web应用程序的重要工具,但它们的使用依赖于特定的需求和上下文。
42 0
|
5月前
|
自然语言处理 前端开发 Java
Servlet与JSP:Java Web开发的基石技术详解
【6月更文挑战第23天】Java Web的Servlet与JSP是动态网页的核心。Servlet是服务器端的Java应用,处理HTTP请求并响应;JSP则是结合HTML与Java代码的页面,用于动态内容生成。Servlet通过生命周期方法如`init()`、`service()`和`destroy()`工作,而JSP在执行时编译成Servlet。两者在MVC架构中分工,Servlet处理逻辑,JSP展示数据。尽管有Spring MVC等框架,Servlet和JSP仍是理解Web开发基础的关键。
105 12
|
5月前
|
存储 Java 关系型数据库
基于Servlet和JSP的Java Web应用开发指南
【6月更文挑战第23天】构建Java Web应用,Servlet与JSP携手打造在线图书管理系统,涵盖需求分析、设计、编码到测试。通过实例展示了Servlet如何处理用户登录(如`LoginServlet`),JSP负责页面展示(如`login.jsp`和`bookList.jsp`)。应用基于MySQL数据库,包含用户和图书表。登录失败显示错误信息,成功后展示图书列表。部署到Tomcat服务器测试功能。此基础教程为深入Java Web开发奠定了基础。
116 10