发表于: 2017-08-29 21:50:00

2 1174


一.今天完成的主要事情

1.准备小课堂

今天完成了小课堂的代码实战部分

建立了一个demo工程,主要演示Filter的作用,Filter完成的功能是,设置字符集,提取隐藏表单中的属性,包装request,敏感词汇过滤等.

字符集过滤器就是在任务中常用的过滤器.

提取隐藏表单中的属性是在前两天的日报中提到的过滤器,能够提取提交的表单中的隐藏属性中定义的HTTP请求方法.

那天在日报中应该也提到,在跳转页面中必须要用"redirect:XXX"这种形式,如果不使用就报405错误.提示方法不对,如图

因为控制器返回的请求和响应的方法是过滤之后的真正的方法,web容器不支持这两种方法,所以会报错,那么今天就用过滤器来解决这个问题.

首先是过滤器的代码.

public class GetMethodConvertingFilter implements Filter {

    @Override

    public void init(FilterConfig config) throws ServletException {

    }

    @Override

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

        throws IOException, ServletException {

    chain.doFilter(wrapRequest((HttpServletRequest) request), response);

    }

    @Override

    public void destroy() {

    }

    private static HttpServletRequestWrapper wrapRequest(HttpServletRequest request) {

        return new HttpServletRequestWrapper(request) {

            @Override

            public String getMethod() {

                return "GET";

            }

        };

    }

}

重点是标粗的那段静态方法,其作用是重写request中的getMethod()方法,将所有请求的方法改为"GET"

然后是web.xml中的配置

配置该过滤器,红框标出的部分是重点,这个标签的含义是,该过滤器只会处理所有由forward方法转发的请求,比如 return "forward: XXX"这种,还有,当控制器返回后,前端控制器会将控制器返回的结果用forward方法转发给视图解析器,也就是说,如果控制器中返回的是jsp页面,那么就必须被该过滤器处理,这样,就可以有效的避免以上错误的发生,而且不用在一个项目的页面相互跳转时用重定向处理.

比如控制器是这样

除了增加这个过滤器,什么也不用更改,使用tomcat8版本跑项目,结果为;

可以完全使用put请求和delete请求了.

然后,继续实现响应字符替换的功能,这次主要使用HttpServletResponseWarpper类,通过该类将响应封装进缓冲区,然后从缓冲区中读取,将字符替换之后再输出到页面.

过滤器中的主要代码:

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

throws IOException, ServletException {

HttpServletRequest httpRequest = (HttpServletRequest) request;

//通过response获取一个ResponseWrapper对象

ResponseWrapper wrapper = new ResponseWrapper((HttpServletResponse) response);

//执行控制器方法

filterChain.doFilter(httpRequest, wrapper);

//通过wrapper获取response请求的内容,然后按照需求替换相应的内容

String result = wrapper.getResult();

result = result.replace("请求", "测试");

//再将流输出

response.setContentLength(-1);

PrintWriter out = response.getWriter();

out.write(result);

out.flush();

out.close();

}




ResponseWrapper类代码为:

public class ResponseWrapper extends HttpServletResponseWrapper{

private PrintWriter cachedWriter;

private CharArrayWriter bufferedWriter;

public ResponseWrapper(HttpServletResponse response){

super(response);

//保存返回结果的缓冲流

bufferedWriter = new CharArrayWriter();

//包装response,让所有结果通过这个PringWriter写入到bufferedWriter中

cachedWriter = new PrintWriter(bufferedWriter);

}

@Override

public PrintWriter getWriter(){

return cachedWriter;

}

public String getResult(){

byte[] bytes = bufferedWriter.toString().getBytes();

try {

return new String(bytes, "UTF-8");

} catch (UnsupportedEncodingException e) {

Log.loggerCreate(LogLevel.ERROR, "转换编码失败,不支持的编码类型" + e.getMessage());

return "";

}

}

}


其中将response的内容转化为流并缓冲的操作就是由标粗的部分完成的.通过wrapper.getResult()方法,获取到response的流,然后对相应字符进行替换,这里将"请求"替换为"测试",运行结果为:

2.优化项目

添加过滤器,将原来需要redirect的部分全部改成forward,因为如果使用redirec的话,是使用重定向的方式,相同于重新请求了一次,不仅效率低,而且如果项目被部署到不同的web容器中,使用不同的根路径时会发生找不到控制器的情况,所以项目内部跳转还是使用forward要更好一些.

具体代码就不贴了,比较简单

请求变为测试

今天讲完小课堂之后才发现没有录屏,又重新录制一遍浪费了不少时间,所以下午从四点之后就没有怎么继续任务,效率有点低.

二.明天的计划

1.测试邮箱第三方API通道

2.如果有时间,将邮箱通道集成到系统中

三.遇到的问题

暂无

四.收获

对于SpringMVC整个流程掌握的更加清晰,对于Filter理解的更加透彻了.

五.项目进度

今天和王蒙讨论了一下任务七,感觉完成不难,但是如果做得质量稍高一些就会比较困难,所以可能会有延期风险.

禅道链接:http://task.ptteng.com/zentao/project-task-259.html




返回列表 返回列表
评论

    分享到