我有一个带有javascript的Spring (v4.1.3) web应用程序。我已经实现了一个自定义DispatcherServlet,并在web.xml中配置了相同的
在UI向服务器发出的每个请求的HTTP头中都有一个独特的屏幕代码。
在自定义dispatcher servlet的doService方法中,我捕获Header并将值放入ThreadLocal dto变量中。我访问服务层中的这个ThreadLocal变量,以执行一些审计逻辑,这对于所有请求来说都是常见的。
来自CustomDispatcherServlet的代码:
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
String uiCode = request.getHeader("uiCode");
if ((uiCode != null && !uiCode.trim().isEmpty())) {
UiCodeDto uiCodeDto = new UiCodeDto(uiCode);
final ThreadLocal<UiCodeDto> threadLocalUser = new ThreadLocal<UiCodeDto>();
threadLocalUser.set(uiCodeDto);
}
...
super.doService(request, response);
}来自服务层的代码:
UiCodeDto temp = ThreadLocalUtil.getUiCodeDto(Thread.currentThread());从ThreadLocalUtil检索ThreadLocal值的代码:
public final class ThreadLocalUtil {
public static UiCodeDto getUiCodeDto(Thread currThread) {
UiCodeDto UiCodeDto = null;
try {
Field threadLocals = Thread.class.getDeclaredField("threadLocals");
threadLocals.setAccessible(true);
Object currentThread = threadLocals.get(currThread);
Field threadLocalsMap = currentThread.getClass().getDeclaredField("table");
threadLocalsMap.setAccessible(true);
threadLocalsMap.setAccessible(true);
Object[] objectKeys = (Object[]) threadLocalsMap.get(currentThread);
for (Object objectKey : objectKeys) {
if (objectKey != null) {
Field objectMap = objectKey.getClass().getDeclaredField("value");
objectMap.setAccessible(true);
Object object = objectMap.get(objectKey);
if (object instanceof UiCodeDto) {
UiCodeDto = (UiCodeDto) object;
break;
}
}
}
} catch (Exception e) {
...
}
return UiCodeDto;
}
}问题如下: 1.我得到了屏幕代码的随机值,这意味着http请求N的值将出现在http请求N+1中。2. ThreadLocal变量中存在空DTO,同名-因此,有时当我访问服务层的ThreadLocal时,我会得到一个null。
在理解ThreadLocal在DispatcherServlet中的行为方面,我需要帮助--为什么它会在doService方法中获得另一个请求的值?
提前谢谢。
发布于 2016-02-03 13:45:59
更多的Spring方法是使用请求范围bean来提取和保存标题:
@Component
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UiCodeDto {
private String uiCode;
@Inject
public void setCode(HttpServletRequest req) {
uiCode = req.getHeader("uiCode");
}
public String getUiCode() {
return uiCode;
}
}您可以像普通的bean一样使用它:
@Service
public class RandomService {
@Inject
UiCodeDto uiCodeDto;
public void handle() {
System.out.println(uiCodeDto.getUiCode());
}
}https://stackoverflow.com/questions/35176357
复制相似问题