Use the implementation filter to wrap the request to get the analysis of the inner request

 

public class ShiroHttpServletRequest extends HttpServletRequestWrapper {

}

 

public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest {}

 

public class ServletRequestWrapper implements ServletRequest {

    private ServletRequest request;

 

    }

 

 

 

request

 

When using the implementation filter for packaging, the setting order of the filter determines the hierarchical relationship of the packaging. Since the previous filter is executed first, the previous request is packaged in the innermost layer.

 

 

Configure ShiroHttpServletRequest as follows to include RemoteSessionRequest (CrossDomainFilter wraps the servelet into RemoteSessionRequest), and ShiroHttpServletRequest wraps the current RemoteSessionRequest again:

 

Therefore, it cannot be directly converted when using it, it needs to be converted after acquisition ((RemoteSessionRequest) ((ShiroHttpServletRequest)request).getRequest()).getSession().setAttribute("q","2");

 

 

RemoteSessionRequest uses dynamic proxy to make corresponding operations operate in redis (that is, operations that change local memory) , which further solves the common problem of some content in distributed requests.

虽然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);

}

 

}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326143661&siteId=291194637