文档章节

jfinal中使用ThreadLocal来绑定request和response

SPPan
 SPPan
发布于 2017/06/05 14:54
字数 1172
阅读 82
收藏 0

在一个web项目中,总会有情况遇到无法直接取到request或者response的时候。例如在jfinal中使用freemarker自定义指令,就无法拿到对应的request和response,于是threadLocal的作用很强大了,以下代码使用jfinal中使用freemarker自定义指令获取request为例。

1、新增一个LocalThreadMapHolder类,用于保存当前线程请求的request和response,定义如下:

package net.sppan.cms.common;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jfinal.kit.Kv;
/**
 * request 和 response 获取钩子
 * @author SPPan
 *
 */
public class LocalThreadMapHolder {
	private static ThreadLocal<Kv> threadLocal = new ThreadLocal<>();
	public static final String REQUEST_KEY = "request_key";
	public static final String RESPONSE_KEY = "response_key";
	
	public static void setThreadLocal(Kv kv){
		threadLocal.set(kv);
	}
	
	public static Kv getThreadLocal(){
		return threadLocal.get();
	}
	
	/**
	 * 获取request
	 * @return
	 */
	public static HttpServletRequest getRequest(){
		return (HttpServletRequest) getThreadLocal().get(REQUEST_KEY);
	}
	/**
	 * 获取response
	 * @return
	 */
	public static HttpServletResponse getResopnse(){
		return (HttpServletResponse) getThreadLocal().get(RESPONSE_KEY);
	}
}

2、定义一个拦截器,用于在接受到有请求的时候将当前线程的request和response放入到threadLocal中。


package net.sppan.cms.interceptor;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.kit.Kv;
import net.sppan.cms.common.LocalThreadMapHolder;
/**
 * 请求线程钩子拦截器
 * 
 * @author SPPan
 *
 */
public class LocalThreadHolderInterceptor implements Interceptor{
	@Override
	public void intercept(Invocation inv) {
		Kv kv = Kv.by(LocalThreadMapHolder.REQUEST_KEY, inv.getController().getRequest()).set(LocalThreadMapHolder.RESPONSE_KEY, inv.getController().getResponse());
		LocalThreadMapHolder.setThreadLocal(kv);
		inv.invoke();
	}
}

3、使用拦截器进行拦截。

@Override
public void configInterceptor(Interceptors me) {
	me.addGlobalActionInterceptor(new LocalThreadHolderInterceptor());
}

4、在自定义指令中获取request和response。


//获取request
HttpServletRequest request = LocalThreadMapHolder.getRequest();
//获取response
HttpServletResponse resopnse = LocalThreadMapHolder.getResopnse();

以下是在网上收集的关于ThreadLocal相关的资料

一、概述

ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。

从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。

通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。

ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。

概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

二、API说明

ThreadLocal()

创建一个线程本地变量。

T get()

返回此线程局部变量的当前线程副本中的值,如果这是线程第一次调用该方法,则创建并初始化此副本。

protected T initialValue()

返回此线程局部变量的当前线程的初始值。最多在每次访问线程来获得每个线程局部变量时调用此方法一次,即线程第一次使用 get() 方法访问变量的时候。如果线程先于 get 方法调用 set(T) 方法,则不会在线程中再调用 initialValue 方法。

若该实现只返回 null;如果程序员希望将线程局部变量初始化为 null 以外的某个值,则必须为 ThreadLocal 创建子类,并重写此方法。通常,将使用匿名内部类。initialValue 的典型实现将调用一个适当的构造方法,并返回新构造的对象。

void remove()

移除此线程局部变量的值。这可能有助于减少线程局部变量的存储需求。如果再次访问此线程局部变量,那么在默认情况下它将拥有其 initialValue。

void set(T value)

将此线程局部变量的当前线程副本中的值设置为指定值。许多应用程序不需要这项功能,它们只依赖于 initialValue() 方法来设置线程局部变量的值。

在程序中一般都重写initialValue方法,以给定一个特定的初始值。

© 著作权归作者所有

共有 人打赏支持
SPPan
粉丝 10
博文 29
码字总数 15103
作品 0
成都
程序员
JFinal-Beetl-Shiro(JdbcRealm)-例子

JFinal-Shiro-JDBC-Demo http://git.oschina.net/yinjun622/JFinal-Shiro-JDBC-Demo 简单实现@JFinal与Shiro整合例子 1、工程通过Eclipse直接导入,部署到tomcat中; 2、新建jfinalshiro数据......

leon_rock
2014/02/27
0
12
给JFinal添加 Sqlite 数据库支持

Sqlite 的单文件便携性、高性能在开发中方便性无与伦比,即使部署在中小型应用中也胜任有余。 在JFinal中添加对 Sqlite 的支持 Step by Step: 1、点击 http://www.xerial.org/maven/reposi...

子午
2012/07/31
0
4
JAVA 极速WEB+ORM框架 - JFinal

JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、p...

JFinal
2012/03/18
0
496
JFinal 中使用 Dubbo —— 1 改造JFinal Demo

Dubbo Demo概述 此Demo实际在2014年上半年就已经完成了,只是到最近才有时间和心情写完此文。同时,将JFinal升级到了1.9,并采用Maven构建项目。 另外,仔细想了想,Provider其实可以不依托T...

糊搞
2015/04/20
0
16
手把手教你新建 jfinal项目 (一)

申明:个人对java web了解不多,水平不足,有搞笑的地方请勿喷。 一、开工了 1、首先上官网下载 jfinal 的jar包和文档 我们要下载带源码的,这样用的时候还能看看源码。 2、使用MyEclipse进行...

胡萝卜炒肉
2014/05/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

golang使用protobuf简易教程

参考文档:https://blog.csdn.net/qq_15437667/article/details/78425151 一、安装protobuf # 去github.com/golang/protobuf下载源码包,# 拷贝到 $GOPATH/src/github.com/golang/protobuf......

科陆李明
31分钟前
0
0
8月16日 上课截图

小丑鱼00
46分钟前
0
0
Nginx负载均衡、配置SSL

Nginx负载均衡 在 /usr/local/nginx/conf/vhost/ 下创建一个文件,写入以下内容 加载后用curl测试可以访问设置的网站 www.qq.com ssl原理 HTTPS是一种加密的http协议,如果HTTP通信的数据包在...

黄昏残影
50分钟前
0
0
String 源码阅读笔记

String源码阅读 本人学习笔记,内容来自于阅读源码和其他博客,水平有限,如有错误,烦请指正。 详情参考: Java 7 源码学习系列(一)——String 请别再拿“String s = new String("xyz");...

等到烟火清凉_
51分钟前
4
0
Coding and Paper Letter(十二)

资源整理。<!-- more --> 1 Coding: 1.R语言生成的ppt,GeoStat2018会议报告,时空模式分析的报告。 geostat18 2.欧空局哨兵和SMOS的工具集,关于对地观测数据的处理与分析的docker容器。 ...

胖胖雕
52分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部