`
y806839048
  • 浏览: 1127081 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

在使用实现过滤器进行request包装,获取内层request的分析

阅读更多

 

public class ShiroHttpServletRequest extends HttpServletRequestWrapper {

}

 

public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest {}

 

public class ServletRequestWrapper implements ServletRequest {

    private ServletRequest request;

 

    }

 

 

 

request

 

在使用实现过滤器进行包装的时候,过滤器的设置顺序决定了包装的层级关系,由于在前面的filter先执行,所以在前面的request是包在最里层的

 

 

如下配置ShiroHttpServletRequest包含RemoteSessionRequest(CrossDomainFilter把servelet包装成RemoteSessionRequest),ShiroHttpServletRequest再一次包装当前的RemoteSessionRequest:

 

所以在使用的时候不可以直接转化,需要获取后再转化((RemoteSessionRequest)((ShiroHttpServletRequest)request).getRequest()).getSession().setAttribute("q","2");

 

 

RemoteSessionRequest用动态代理的方式使得相应的操作在redis中操作(即改变本地内存的操作),解决进一步解决了分布式中request中一些内容的公用,

虽然shiro可以集成使用redis实现session共享(使得更多的内容以更多的方式实现共享)

 

CrossDomainFilter:同时也做了跨域的request修饰包装

 

web.xml:

 

 

<filter>

<filter-name>cors</filter-name>

<filter-class>com.common.CrossDomainFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>cors</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

 

  <display-name>Acegi Security Tutorial Application</display-name>

  <!--loginFilter 用来过滤登录信息的,如果账号密码有误,不能登录 -->

  <filter>

<filter-name>shiroFilter</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

<init-param>

<param-name>targetFilterLifecycle</param-name>

<param-value>true</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>shiroFilter</filter-name>

<url-pattern>/*</url-pattern>

<dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>

</filter-mapping>

<filter>

<filter-name>loginFilter</filter-name>

<filter-class>core.apps.rbac.login.LoginFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>loginFilter</filter-name>

<url-pattern>/j_acegi_security_check</url-pattern>

</filter-mapping>

 

 

 

 

 

 

 

 

 

 

java:

 

 

package com.common;

 

import core.session.filter.RemoteSessionRequest;

 

import java.io.IOException;

import java.util.Arrays;

import java.util.Enumeration;

import java.util.Vector;

 

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;

import javax.servlet.http.HttpServletResponse;

 

 

 

 

 

 

public final class CrossDomainFilter implements Filter {

private static final String VAL_ACCESS_CONTROL_ALLOW_ORIGIN = "*";

private static final String VAL_ACCESS_CONTROL_ALLOW_HEADERS = new StringBuilder(

"Origin,X-Requested-With,Content-Type,Accept").toString();

 

//    .append("," + AuthenticationConstants.X_AUTH_TOKEN)

//    .append("," + VersionDispatchFilter.HEADER_APP_VERSION)

 

    private static final String VAL_ACCESS_CONTROL_ALLOW_METHODS = "GET,POST,PUT,DELETE,OPTIONS";

 

@Override

public void init(FilterConfig filterConfig) throws ServletException {

 

}

 

@Override

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

throws IOException, ServletException {

HttpServletResponse httpResponse = (HttpServletResponse) response;

HttpServletRequest httpRequest = (HttpServletRequest) request;

 

httpResponse.addHeader("Access-Control-Allow-Origin", VAL_ACCESS_CONTROL_ALLOW_ORIGIN);

httpResponse.addHeader("Access-Control-Allow-Headers", VAL_ACCESS_CONTROL_ALLOW_HEADERS);

httpResponse.addHeader("Access-Control-Allow-Methods", VAL_ACCESS_CONTROL_ALLOW_METHODS);

httpResponse.addHeader("P3P", "CP=CAO PSA OUR");

if ("application/x-www-form-urlencoded".equals(httpRequest.getHeader("content-type"))) {

httpRequest = new CrossRequestWrapper(httpRequest);

}

 

try {

//if ("get".equals(httpRequest.getMethod().toLowerCase()) && StringUtils.isNotBlank(httpRequest.getParameter(AuthenticationConstants.X_AUTH_TOKEN))) {

//httpRequest.setAttribute(AuthenticationConstants.X_AUTH_TOKEN, httpRequest.getParameter(AuthenticationConstants.X_AUTH_TOKEN).trim());

//}

            if ("get".equals(httpRequest.getMethod().toLowerCase()) ) {

//                httpRequest.setAttribute(AuthenticationConstants.X_AUTH_TOKEN, httpRequest.getParameter(AuthenticationConstants.X_AUTH_TOKEN).trim());

            }

} catch (Throwable e) {

 

}

chain.doFilter(new RemoteSessionRequest((HttpServletRequest) httpRequest), response);

}

 

@Override

public void destroy() {

 

}

 

private class CrossRequestWrapper extends HttpServletRequestWrapper {

private CrossRequestWrapper(HttpServletRequest httpRequest) {

super(httpRequest);

}

 

@Override

public String getHeader(String name) {

if ("content-type".equals(name.toLowerCase())) {

return "application/json";

}

return super.getHeader(name);

}

 

@Override

public Enumeration<String> getHeaders(String name) {

if ("content-type".equals(name.toLowerCase())) {

return new Vector<String>(Arrays.asList("application/json")).elements();

}

return super.getHeaders(name);

}

 

 

public Enumeration<String> getHeaderNames() {

return super.getHeaderNames();

}

 

@Override

public String getContentType() {

return "application/json";

}

}

 

/*private class AuthTokenHttpServletRequest extends HttpServletRequestWrapper {

private final String requestBody;

public AuthTokenHttpServletRequest(HttpServletRequest request, String requestBody) {

super(request);

this.requestBody = requestBody;

}

 

public ServletInputStream getInputStream() {

try {

return new ByteServletInputStream(new ByteArrayInputStream(requestBody.getBytes("UTF-8")));

} catch (Throwable e) {

log.error("", e);

}

return null;

}

}

 

private class ByteServletInputStream extends ServletInputStream  {

private ByteArrayInputStream byteInputStream;

private ByteServletInputStream(ByteArrayInputStream byteInputStream) {

this.byteInputStream = byteInputStream;

}

 

@Override

public boolean isFinished() {

return byteInputStream.available() <= 0;

}

 

@Override

public boolean isReady() {

return true;

}

 

@Override

public void setReadListener(ReadListener readListener) {

// TODO Auto-generated method stub

 

}

 

@Override

public int read() throws IOException {

return byteInputStream.read();

}

 

}*/

}

 

 

 

RemoteSessionRequest:(提供动态代理拦截)代理了session

 

WebSessionManager  进行redis操作

 

 

 

 

 

package core.session.filter;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.HashMap;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import javax.servlet.http.HttpSession;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import core.session.manager.RedisTemplateDelegate;

import core.session.manager.WebSession;

import core.session.manager.WebSessionManager;

import lombok.extern.log4j.Log4j2;

 

/**

 * 

 * <p>通过继承HttpServletRequestWrapper 来实现</p>

 * @author houzhanshan

 * @version $Id: RemoteSessionRequest.java, v 0.1 2017年5月26日 下午11:40:51 houzhanshan Exp $

 */

public class RemoteSessionRequest extends HttpServletRequestWrapper {

public RemoteSessionRequest(HttpServletRequest request) {

super(request);

}

 

@Override

public HttpSession getSession() {

return RemoteSessionHandler.getInstance(super.getSession());

}

}

@Log4j2

class RemoteSessionHandler implements InvocationHandler {

// 模拟远程Session服务器,Key表示SessionId,Value表示该Session的内容

private static Map<String, Map<String, Object>> map = new ConcurrentHashMap<String, Map<String, Object>>();

private static Logger log= LoggerFactory.getLogger(RedisTemplateDelegate.class);

private HttpSession session = null;

 

private RemoteSessionHandler(HttpSession httpSession) {

this.session = httpSession;

};

 

public static HttpSession getInstance(HttpSession httpSession) {

InvocationHandler handler = new RemoteSessionHandler(httpSession);

return (HttpSession) Proxy.newProxyInstance(httpSession.getClass().getClassLoader(), httpSession.getClass().getInterfaces(), handler);

}

 

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

if ("setAttribute".equals(method.getName())) {

String id = session.getId();

Map<String, Object> m = map.get(id);

if (m == null) {

m = new HashMap<String, Object>();

 

}

WebSession webSession=WebSessionManager.getInstance().getSession(id);

if(webSession==null){

webSession=WebSessionManager.getInstance().createSession(id);

}else{

webSession=WebSessionManager.getInstance().getSession(id);

 

}

webSession.setAttribute((String) args[0], args[1]);

log.info("[存入]key:" + args[0] + ",value:" + args[1]);

return null;

} else if ("getAttribute".equals(method.getName())) {

String id = session.getId();

WebSession webSession= WebSessionManager.getInstance().getSession(id);

if(webSession==null){

return null;

}

Object result = webSession.getAttribute((String) args[0]);

log.info("[取出]key:" + args[0] + ",value:" + result);

return result;

}

return method.invoke(session, args);

}

 

}

 

分享到:
评论

相关推荐

    SSM登陆验证之过滤器实现

    SSM(Spring、SpringMVC、MyBatis)框架是Java Web开发中常见的技术栈,其在处理用户请求时,通常会用到过滤器(Filter)进行预处理,以实现如登录验证等功能。本篇文章将深入讲解如何在SSM项目中通过过滤器实现登录...

    过滤器的基本用法

    在`doFilter()`方法内,我们可以对请求和响应进行处理,并调用`filterChain.doFilter()`来传递请求到下一个过滤器或目标资源。 例如,以下是一个简单的字符编码转换过滤器的实现: ```java import javax.servlet.*...

    过滤器(实现粗颗粒权限控制).zip

    在IT行业中,过滤器(Filter)是Web应用程序中一个重要的概念,主要用于实现预处理和后处理请求的功能。在这个“过滤器(实现粗颗粒权限控制)”的案例中,我们主要探讨如何利用过滤器来实现登录权限的粗粒度控制,...

    基于USB设备的过滤器驱动程序算法分析

    ### 基于USB设备的过滤器驱动程序算法分析 #### 摘要与背景介绍 在Windows Driver Model (WDM)...此外,由于过滤器驱动程序的设计和实现相对灵活,可以根据具体需求进行定制,因此在实际应用中具有很高的实用价值。

    Wireshark网络分析实例集锦—第3章__捕获过滤器技巧.pdf

    ### Wireshark网络分析实例集锦—第3章__捕获过滤器技巧 #### 捕获过滤器技巧概述 本章节重点介绍了Wireshark中的捕获过滤器技巧,这对于提高数据分析效率至关重要。通过合理设置捕获过滤器,可以在抓取网络数据时...

    Laravel开发-laravel-middleware-request-id

    Middleware 可以看作是请求进入应用前和响应离开应用后的一个过滤层,允许开发者执行一系列自定义操作,比如认证、日志记录、路由权限等。`laravel-middleware-request-id` 是一个专门为 Laravel 设计的中间件,它的...

    使用ARP协议获取局域网内部活动主机物理地址的程序实现C++广工计算机网络课程设计.docx

    1. 使用Winpcap库初始化网络接口,设置捕获过滤器,以便只捕获ARP相关的封包。 2. 编写`packet_handler`函数,该函数会在接收到每个封包时被调用,检查封包类型是否为ARP,并进一步判断是请求还是应答。 3. 解析ARP...

    wireshark过滤器-抓包教程大全!

    - **应用层过滤器**:对于HTTP协议,`http.contains`和`http.request.uri`可以查找特定请求或响应内容,`http.response.code`用于筛选特定HTTP状态码。 3. **时间过滤**:`frame.time`可以用来匹配或筛选特定时间...

    Flask中获取小程序Request数据的两种途径

    同时,在业务逻辑层,需要对数据进行相应的处理,以满足业务需求。 总结来说,通过Flask获取小程序数据的两种主要途径包括直接使用Flask的Request对象和借助Flask-WTF扩展。这两种方法各有优势,开发者应根据具体的...

    JavaWebServlet+JSP+EL表达式+JSTL标签库+Filter过滤器+Listener监听器

    5. **Filter过滤器**:过滤器在Servlet规范中定义,可以在请求到达目标Servlet或JSP之前对请求进行预处理,也可以在响应返回给客户端之前进行后处理。常见的用途有字符编码转换、权限控制、日志记录等。过滤器通过...

    Laravel开发-filterable

    除了在控制器中应用过滤器,还可以使用中间件来全局处理过滤逻辑。创建一个新的中间件,然后在`app/Http/Kernel.php`中注册它,这样所有经过该中间件的请求都会自动应用过滤。 六、性能优化 为了提高性能,可以使用...

    Laravel开发-laravel-request-sanitizer

    这个包提供了优雅的方式来过滤、验证和转换用户提交的数据,避免了在控制器或服务层中编写大量重复的清理代码。 ### 请求输入清理的重要性 在Web应用中,用户提交的数据往往未经验证,可能包含恶意内容或不符合...

    servlet最简单实现mvc三层,使用的是2.5版本的xml文件

    在Servlet 2.5版本中,Web应用的部署描述符`web.xml`用于配置Servlet、过滤器和监听器。在MVC框架中,我们可能会配置以下内容: - **Servlet配置**:定义Servlet的类名、URL映射等,如`&lt;servlet&gt;`和`...

    ethereal filter使用

    显示过滤器则是在数据包被读取后,用来筛选出感兴趣的特定数据包进行查看的过滤器。这有助于用户快速定位和分析关键信息。Ethereal的显示过滤器提供了非常强大的表达式语言,可以实现复杂的数据包匹配条件。 #### ...

    笔试JSP1.doc

    在 JSP 中,可以使用 `request.getRemoteAddr()` 方法获取访问者的 IP 地址。 5. forward 和 redirect forward 和 redirect 是两种不同的页面跳转机制: * forward:在服务器端跳转,客户端不知道跳转的过程 * ...

    Android-OkLogOkHttp的响应记录拦截器

    总结来说,通过使用OkHttp的响应记录拦截器,开发者可以轻松地监控网络请求,获取详细的请求和响应信息,这对于调试、性能分析以及问题定位具有极大的帮助。同时,结合OkLog这样的强大日志库,可以使得日志输出更加...

    Apache Solr 架构分析内部设计篇PDF

    - **运行时分析器**:可以在运行时从分词器和过滤器构建分析器。 ##### 2.2 对于开发者而言的Solr - **Java Web应用**:Solr是一个基于Java 5的Web应用程序(WAR包),提供了类似Web服务的API。 - **可扩展的插件...

    javaweb方立勋视频源码

    6. **过滤器(Filter)**:过滤器允许在请求被Servlet处理之前或之后进行拦截,可以实现如字符编码转换、登录检查等功能。源码中可能包含了自定义过滤器的实现。 7. **监听器(Listener)**:监听器用于监听特定...

    JavaWeb.pdf

    多个 Filter 过滤器的特点是它们都使用同一个 Request 对象,执行在同一个线程中。 Filter 的配置文件是指在 web.xml 中的 Filter 配置信息。 Tomcat 是一种 Web 服务器,用于运行 JavaWeb 应用程序。 Filter 的...

Global site tag (gtag.js) - Google Analytics