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

request包装的,实现request属性共享内存管理

阅读更多

 

过滤器包装request的,可以实现一些共享的属性,比如将request中的attr从redis中获取等有利于集群,

层次特性:在越下面的过滤器包在越外层

 

 以前不用包的requets本地内存,后面包了的内层requets是redis内存,所有需要共享的放在内层request,一般的放在外层request即可

 

设计思路:

以前不用包的requets本地内存,后面包了的内层requets是redis内存,所有需要共享的放在内层,一般的放在外层即可,一般的项目都是开始用的是本地的requst,如果需要改造的话必定是大量已经用了本地内存的request,此时只要把新加的操作redis的requset放在内层即可--->体现在配置上就是放在内层的配置在前面,放在外层的配置在后面,外层的就是最常规的用法用的

 

shirohttprequest--->普通的request存在本地内存

    remotequest--->内包了自定义的requst,这个requst用了代理模式,只要用到这个对象的session的set,getattribute()方式就进入代理,这个里面调用sessionmanager操作redis的内存

         sessionmanager-->操作redis的内存工具

 

 

 ==================================

注意其中的RemoteSessionRequest以前用的是代理sessionid创建获取session,用这个会一次请求生成一个代理,所以又是不同的session,导致后面拿不到,这里改造直接用用户代码做id:

 WebSessionid用用户代码,用户代码放在内存中,用jsession+"username"为key,详见后面的文章

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

}

 

 

HttpServletRequest request1 =(HttpServletRequest) ((WebSubject)SecurityUtils.getSubject()).getServletRequest();

String id = session.getId();//用这个会一次请求生成一个代理,所以又是不同的session,导致后面拿不到

 

/if(args.length == 3){

id=shiroUser.getUserId();//创建一个固定的session

//}

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

 ================================================================

 

WebSessionManager就是session在redis内存中的具体操作

 

((RemoteSessionRequest)((ShiroHttpServletRequest)request).getRequest()).getSession().setAttribute("q","2");

((RemoteSessionRequest)((ShiroHttpServletRequest)request).getRequest()).getSession().getAttribute("q");

 



 

 

 另:

request在不同的代码包装的层次大同小异,比如由action获得的request里面有shirohttprequest再里面才有RemoteSessionRequest这种包装的request

 

ShiroHttpServletRequest srequest=(ShiroHttpServletRequest) ((StrutsRequestWrapper)ServletActionContext.getRequest()).getRequest();
Integer dispatchCustHQLForQueryCount =(Integer)(((RemoteSessionRequest)srequest.getRequest()).getSession().getAttribute("dispatchCustHQLForQueryCount"));//session.getAttribute("dispatchCustHQLForQueryCount");


 

 

<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>

 

 

 

 

<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>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

    </filter>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

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

        <dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>

    </filter-mapping>

 

 

    越在后面的被包在越外层

 

 

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

//chain.doFilter(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();

}

 

}*/

}

 

 

 

 

 

 

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

}

 

}

 

  • 大小: 20.5 KB
  • 大小: 21.3 KB
分享到:
评论

相关推荐

    Visual C++实践与提高-COM和COM+篇『PDF』

    13.5 利用共享属性管理器共享状态——例程Steps 13.5.1 共享属性管理器 13.5.2 修改Step4程序 13.5.3 测试组件 13.6 使用多事务处理——例程Step6 13.6.1 修改Step5程序 13.6.2 测试组件 13.7 使用基于角色的安全性...

    超级有影响力霸气的Java面试题大全文档

     final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 finally是异常处理语句结构的一部分,表示总是执行。 finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的...

    java基础问答 txt

    - **Model**:负责数据管理和业务逻辑,通常由 JavaBean 或者其他数据结构实现。 - **View**:负责显示用户界面,通常由 JSP 页面实现。 - **Controller**:负责接收用户请求、调用模型进行业务处理并决定使用哪个...

    ****大公司的面试题.doc

    - **垃圾回收(Garbage Collection, GC)**:Java的自动内存管理机制,负责回收不再使用的对象所占用的内存。 - **接口(Interface)**:Java中用于定义行为规范的抽象类型,一个类可以实现多个接口,实现多继承...

    远光软件股份有限公司 最新复试题

    - 在MySQL中,可以先查询自增主键ID,然后再根据这些ID查找具体的行记录,这种方法可以减少内存使用,提高查询效率。 #### Servlet的生命周期 - **加载**:服务器启动时,通过类加载器加载servlet类。 - **创建**...

    华为JAVA笔试面试题

    继承则是指一个类可以继承另一个类的属性和方法,从而实现代码的复用。多态是指一个接口可以有多种不同的实现,或者一个类的对象可以按照多种类型来对待。 【String的基本数据类型】 在Java中,String不是一种基本...

    java知识点.pdf

    - 在Java中,内存管理是至关重要的,主要分为堆内存和栈内存。堆内存用于存放对象实例,而栈内存用于存放局部变量等。理解垃圾回收机制对于编写高效、可靠的Java应用程序至关重要。 **3. 递归** - 递归是一种通过...

    java华为面试题

    该程序使用了内部类来实现线程,通过`synchronized`关键字确保了对共享变量的访问是线程安全的。 #### 九、JSP的内置对象及方法 - **request**:`HttpServletRequest`对象,用于获取客户端发送的请求信息。 - **...

    面试宝典总结

    - **Integer**: 对应的包装类,实现了Integer接口。可以使用null值,可用于泛型等。 **重载和重写的区别** - **重载(Overloading)**: 在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可。 - ...

    JAVA面试题

    1. **封装**:封装是指将数据和操作数据的方法绑定在一起作为一个整体,隐藏对象的属性和实现细节,仅对外提供公共访问方式。这种机制使得对象成为了一个黑箱,外部只能通过暴露的接口与对象交互。 2. **继承**:...

    huawei面试题--java篇

    2. **继承性**:继承是指子类可以自动拥有父类的属性和行为。这使得代码复用成为可能,并且支持多态性。 3. **多态性**:多态是指一个接口或类可以有多种形态。通过继承和方法重写实现,在不同场合表现出不同的行为...

    Java英文单词汇总编程资料java应届毕业生笔试题编程资料

    - **GC**(Garbage Collection): 垃圾回收机制,自动管理内存,回收不再使用的对象。 2. **short s1赋值运算符比较** - `short s1 = 1; s1 += 1;`能够正确执行,因为`+=`操作符会自动将计算结果转换为`short`...

    华为java面试题.doc

    2. 继承(Inheritance):子类继承父类的属性和行为,实现代码重用和扩展。 3. 多态(Polymorphism):一个对象可以以不同的形式出现,例如方法重载和方法重写。 4. 抽象(Abstraction):将复杂的系统分解成简单的...

    java最经典面试题.doc

    - **实现Callable接口**:使用`FutureTask`包装`Callable`任务,再通过`Thread`执行,这种方式支持返回结果。 - **同步实现方法**: - **synchronized关键字**:可以作用于方法或者代码块,保证同一时刻只有一个...

    华为java面试题(word文档)

    int在内存中直接存储数值,而Integer在内存中存储的是对象,占用更多空间。此外,Integer提供了一些额外的方法,如compare()、parseInt()等。 4. **String与StringBuffer的区别**:String是不可变的,每次修改都会...

    JavaEE技术面试常见问题.doc

    例如,可以用汽车的例子来理解这些概念:汽车可以视为一个类,其中包含了各种属性(如颜色、型号等),并通过不同的方法实现其功能(如启动、加速等)。 2. **对象实例化方式及区别** - **使用构造函数**:最...

    java经典面试题

    - 共享内存:允许多个进程共享同一段内存区域。 - 套接字:允许不同进程间的网络通信。 6. **什么是虚拟内存**: - 虚拟内存是一种技术,它让程序可以使用比实际物理内存更大的地址空间。 7. **...

Global site tag (gtag.js) - Google Analytics