将登录等信息保存到session中和退出session
JShop简介:jshop是一套使用Java语言开发的B2C网店系统,致力于为个人和中小企业提供免费、好用的网店系统。
项目主页:http://git.oschina.net/dinguangx/jshop
在线演示:
- 前台: http://jshop.ofmall.org:81/jshop
- 后台: http://jshop.ofmall.org:81/jshop/manage/user/login (admin/123456)
在spring mvc中,为了随时都能取到当前请求的request对象,可以通过RequestContextHolder的静态方法getRequestAttributes()获取Request相关的变量,如request, response等。
在jshop中,对RequestContextHolder的使用进一步封装,简化为RequestHolder类,如下:
public class RequestHolder {
public static HttpServletRequest getRequest(){
HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
return req;
}
<span class="hljs-keyword">public <span class="hljs-keyword">static HttpServletResponse <span class="hljs-title">getResponse(){</br>
HttpServletResponse resp = ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();</br>
<span class="hljs-keyword">return resp;</br>
}</br></br>
}
在大部分的情况下,它都能很好地工作,但在商品管理编辑中,新增商品时,却出现了意外的问题:通过RequestHolder.getRequest().getParameter()得不到参数值,通过debug发现,
通过spring mvc的method注入的request对象实际为MultipartHttpServletRequest,而通过RequestHolder.getRequest()获取到的request对象却是org.apache.catalina.connector.RequestFacade的实例。
public class RequestFacade implements HttpServletRequest
原来在商品新增时,由于使用了文件上传,form表单的enctype类型为”multipart/form-data”,
spring mvc对文件上传的处理类实际却为spring-mvc.xml文件中配置的CommonsMultipartResolver,
该类先判断当前请求是否为multipart类型,如果是的话,将request对象转为MultipartHttpServletRequet,相关的源码见DisptcherServlet
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
......
processedRequest = checkMultipart(request);
multipartRequestParsed = processedRequest != request;
......
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
......
}
<span class="hljs-keyword">protected HttpServletRequest <span class="hljs-title"><span style="color: #ff0000; font-size: 14pt;"><strong>checkMultipart</strong></span>(HttpServletRequest request) <span class="hljs-keyword">throws MultipartException {</br>
<span class="hljs-keyword">if (<span class="hljs-keyword">this.multipartResolver != <span class="hljs-keyword">null && <span class="hljs-keyword">this.multipartResolver.isMultipart(request)) {</br>
<span class="hljs-keyword">if (request <span class="hljs-keyword"><span style="color: #ff0000; font-size: 14pt;"><strong>instanceof MultipartHttpServletRequest</strong></span>) {</br>
logger.debug(<span class="hljs-string">"Request is already a MultipartHttpServletRequest - if <span style="color: #0000ff; font-size: 18pt;"><strong>not in a forward</strong></span>, " +</br>
<span class="hljs-string">"this typically results from an additional MultipartFilter in web.xml");</br>
}</br>
<span class="hljs-keyword">else {</br>
<span class="hljs-keyword">return <span class="hljs-keyword">this.multipartResolver.<span style="color: #0000ff; font-size: 14pt;"><strong>resolveMultipart</strong></span>(request);</br>
}</br>
}</br>
<span class="hljs-comment">// If not returned before: return original request.</br>
<span class="hljs-keyword">return request;</br>
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
那么,RequestContextHolder中的request又是从哪来的呢?
继续翻看DispatcherServlet的源码,从其父类FrameworkServlet中找到的processRequest()以相关方法源码:
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
......
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();</br>
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);</br></br>
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);</br>
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), <span class="hljs-keyword">new RequestBindingInterceptor());</br></br>
initContextHolders(request, localeContext, requestAttributes);</br></br>
<span class="hljs-keyword">try {</br>
doService(request, response);</br>
}</br>
......</br>
}</br>
<span class="hljs-keyword">protected ServletRequestAttributes <span class="hljs-title"><span style="color: #ff0000; font-size: 14pt;"><strong>buildRequestAttributes</strong></span>(</br>
HttpServletRequest request, HttpServletResponse response, RequestAttributes previousAttributes) {</br></br>
<span class="hljs-keyword">if (previousAttributes == <span class="hljs-keyword">null || previousAttributes <span class="hljs-keyword"><span style="color: #ff0000; font-size: 14pt;"><strong>instanceof ServletRequestAttributes</strong></span>) {</br></br>
<span class="hljs-keyword">return <span class="hljs-keyword">new ServletRequestAttributes(request);
}</br>
<span class="hljs-keyword">else {</br>
<span class="hljs-keyword">return <span class="hljs-keyword">null; <span class="hljs-comment">// preserve the pre-bound RequestAttributes instance</br>
}</br>
}</br></br>
<span class="hljs-keyword">private <span class="hljs-keyword">void <span class="hljs-title">initContextHolders(</br>
HttpServletRequest request, LocaleContext localeContext, RequestAttributes requestAttributes) {</br></br>
<span class="hljs-keyword">if (localeContext != <span class="hljs-keyword">null) {</br>
LocaleContextHolder.setLocaleContext(localeContext, <span class="hljs-keyword">this.threadContextInheritable);</br>
}</br>
<span class="hljs-keyword">if (requestAttributes != <span class="hljs-keyword">null) {</br>
RequestContextHolder.setRequestAttributes(requestAttributes, <span class="hljs-keyword">this.threadContextInheritable);</br>
}</br>
<span class="hljs-keyword">if (logger.isTraceEnabled()) {</br>
logger.trace(<span class="hljs-string">"Bound request context to thread: " + request);</br>
}</br>
}</br>
从这里可以看到,initContextHolder()方法中完成了RequestContextHolder的requestAttributes设置,
而doService()在这之后调用,DispatcherServlet中的processRequest()方法即在doService()之中,
所以从RequestContextHolder中获取到的就是原来的RequestFacade对象,而不是经过spring mvc处理之后的MultipartHttpServletRequest对象,
其后果就是,从RequestContextHolder获取request后,无法直接通过getParameter()获取参数值。
最便捷的解决办法:
直接将HttpServletRequest作为spring mvc的方法入参,即可以正确获取参数值。
http://dinguangx.iteye.com/blog/2227049
将登录等信息保存到session中和退出session的更多相关文章
- 将用户信息保存到Cookie中
/** * 把用户保存到Cookie * * @param request * @param response * @param member */ private void rememberPwdA ...
- SWIFT中将信息保存到plist文件内
在项目中可能我们需要保存一些数据到plist文件中,以下就本人在学习过程中的笔记,不成熟的地方请指出. 可能我有一个类叫做Student import UIKit class Student: NSO ...
- 爬取豆瓣电影信息保存到Excel
from bs4 import BeautifulSoup import requests import html.parser from openpyxl import Workbook,load_ ...
- DOS命令将黑框中查询到的信息保存到TXT等文件里
- python爬取当当网的书籍信息并保存到csv文件
python爬取当当网的书籍信息并保存到csv文件 依赖的库: requests #用来获取页面内容 BeautifulSoup #opython3不能安装BeautifulSoup,但可以安装Bea ...
- Python scrapy爬虫数据保存到MySQL数据库
除将爬取到的信息写入文件中之外,程序也可通过修改 Pipeline 文件将数据保存到数据库中.为了使用数据库来保存爬取到的信息,在 MySQL 的 python 数据库中执行如下 SQL 语句来创建 ...
- 将Prometheus alerts保存到elasticsearch
Prometheus产生的告警通常会发送到alertmanager,当使用alertmanager时,其告警信息仅存在于alertmanager的内存中,无法持久化.故实现了小工具,用于将Promet ...
- Introduction and use of Cookie and Session(Cookie&Session的介绍和使用)
一.Cookie 1.什么是Cookie? Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据. 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来 ...
- 利用session_set_save_handler()函数将session保存到MySQL数据库中
PHP保存session默认的是采用的文件的方式来保存的,这仅仅在文件的空间开销很小的windows上是可以采用的,但是如果我们采用uinx或者是liux上的文件系统的时候,这样的文件系统的文件空间开 ...
随机推荐
- AJPFX关于java中可访问控制符和非访问控制符的详细总结
1.类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1 )公共类修饰符 pub ...
- poj1862 Stripies
思路: 简单贪心. 实现: #include <iostream> #include <cstdio> #include <algorithm> #include ...
- 7z解压参数
7z.exe x D:/test/dwpath/xxx.zip -oD:/test/dwpath/ -aoa
- PMP项目管理学习笔记(5)——整合管理之制定项目章程
关于两个输入 在很多过程中,会用到这两个输入: 企业环境要素 是关于你的公司如何开展业务所需要知道的所有信息. 在你计划项目时,有很多关于公司的信息会非常有用,你需要知道各个不同部门是如何运作的,你所 ...
- Sql Server 2012 分页方法分析(offset and fetch)
最近在分析 Sql Server 2012 中 offset and fetch 的新特性,发现 offset and fetch 无论语法的简洁还是功能的强大,都是相当相当不错的.其中 offse ...
- C# 递归读取XML菜单数据
在博客园注册了有4年了,很遗憾至今仍未发表过博客,趁周末有空发表第一篇博客.小生不才,在此献丑了! 最近在研究一些关于C#的一些技术,纵观之前的开发项目的经验,做系统时显示系统菜单的功能总是喜欢把数据 ...
- 如何开发、本地测试、发布 Laravel 扩展包?
如何开发.本地测试.发布 Laravel 扩展包? Laravel/ 1年前/ 4022 / 11 现在已经有了很多,关于如何开发 Laravel 扩展包的文章.但是大多文章写的太过片面,不 ...
- dnsquery - 使用解析程序查询域名服务器
SYNOPSIS(总览) dnsquery [-n nameserver ] [-t type ] [-c class ] [-r retry ] [-p period ] [-d ] [-s ] [ ...
- 解决WampServer窗口界面乱码问题
软件版本:WampServer 3.1.4 问题描述:Wamp安装完成.点击图标,发现导航界面乱码,也可能使用中没遇到这种问题.如下: 用记事本打开 wampmanager.ini 和 wampman ...
- 阿里云ECS搭建node/mongodb开发环境及部署
一.前端的er在window或mac上安装开发环境应该再清楚不过了.但在服务器上安装还是有点不同的,毕竟是 centOS,从此不得不走上用命令操作…… 二.前期准备 1.首先,我们去阿里云网站阿里云服 ...