jsp取addFlashAttribute值深入理解即springMVC发redirect传隐藏参数
结论:两种方式
a.如果没有进行action转发,在页面中el需要${sessionScope['org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS'][0]['userId']}
b.如果进行了action转发则el直接${userId}
背景:框架中,两个web工程a,b,我的b工程开发了一个对外action接口,a来连,要实现的功能是,a的页面发起一个action请求,到达b的springmvc,通过验证后,打开一个b工程新的tab的新窗口,前端发请求可参考我的另一文章springMVC接受json并打开新页面
1.不进行action转发
controller代码:
@Controller
@RequestMapping("/page/login")
public class LoginController { @RequestMapping(value = "/redirect.do")
public String doRedirect(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("userId", "ID001");
redirectAttributes.addFlashAttribute("userName", "mike");
redirectAttributes.addAttribute("flag", "opening");
return "redirect:../public/indexTest.jsp";
}
}
jsp
<body>
here is indexTest.jsp <br>
userId is ${sessionScope['org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS'][0]['userId']}<br>
userName is ${userName}<br>
flag is ${flag}
param_flag is ${param.flag}
</body>
这样可以正常输出 url:http://lolcalhost:8080/project/page/public/indexTest.jsp?flag=opening
here is indexTest.jsp
userId is ID001
userName is
flag is
param_flag is opening
在jsp中打印session和request
<%
System.out.println("page session parameter:");
//final HttpSession session = request.getSession();
final Enumeration se = session.getAttributeNames();
while (se.hasMoreElements()) {
final String key = (String) se.nextElement();
System.out.println(key + "==" + session.getAttribute(key));
} System.out.println("print redirectpage page request parameter:");
final Enumeration reqEnum = request.getParameterNames();
while (reqEnum.hasMoreElements()) {
final String s = (String) reqEnum.nextElement();
System.out.println(s + "==" + request.getParameter(s));
} System.out.println("print redirectpage page request attribute:");
final Enumeration reqEnum2 = request.getAttributeNames();
while (reqEnum2.hasMoreElements()) {
final String s = (String) reqEnum2.nextElement();
System.out.println(s + "==" + request.getAttribute(s));
}
%>
console输出
page session parameter:
org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS==[FlashMap [attributes={userId=ID001, userName=mike}
, targetRequestPath=/project/page/public/indexTest.jsp, targetRequestParams={flag=[opening]}]]
print redirectpage page request parameter:
flag==opening
print redirectpage page request attribute:
说明:addFlashAttribute方法将参数放入了session中的flashmap中保存起来了,并且隐藏起来,不在浏览器中显示参数,同时传大对象也不受浏览器限制。而redirectAttributes.addAttribute方法则是将参数放到request域中。而且session.getAttribute("org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS")出来的值不是标准的数组,用JSON.parse(str)运行时会报错,只能用el取。
不足:取值过于复杂
2.通过action二次转发
controller
@Controller
@RequestMapping("/page/login")
public class LoginController { @RequestMapping(value = "/redirect.do")
public String doRedirect(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("userId", "ID001");
redirectAttributes.addFlashAttribute("userName", "mike");
redirectAttributes.addAttribute("flag", "opening");
return "redirect:../public/winOpenSucc.do";
}
@RequestMapping(value = "/winOpenSucc.do")
public String redirectPage() {
return "../public/indexTest.jsp"
}
}
jsp页面代码不变
输出 url:http://lolcalhost:8080/project/page/public/winOpenSucc.do?flag=opening
here is indexTest.jsp
userId is
userName is mike
flag is
param_flag is opening
jsp中session,request打印结果
page session parameter:
print redirectpage page request parameter:
flag==opening
print redirectpage page request attribute:
javax.servlet.forward.request_uri==/project/page/login/winOpenSucc.do
javax.servlet.forward.context_path==/project
javax.servlet.forward.servlet_path==/page/login/winOpenSucc.do
javax.servlet.forward.query_string==flag=opening
org.springframework.web.servlet.DispatcherServlet.INPUT_FLASH_MAP==FlashMap [attributes={userId=ID001, userName=mike}, targetR
equestPath=/project/page/login/winOpenSucc.do, targetRequestParams={flag=[opening]}]
userId=ID001
userName=mike
说明:通过action二次转发(默认 return "forward:url"),session中flashmap消失了,通过model(model,modelmap,@ModelAttribute都可以取到前一个action的包括flashAtrribute等参数)这个springmvc这个默认内置对象来接收第一个action redirect过来session中的参数,并自动保存在返回的model数据模型中,forward request依然延续存活(falg依然在值未变),并最终由spring转为request 的attribute中( ${userName}取到了值 )。
不足:浏览器中 url并没有改变,显示为action地址,没有达到需求
3.实现url改变并跟踪model的变化
3.1controller
@Controller
@RequestMapping("/page/login")
public class LoginController { @RequestMapping(value = "/redirect.do")
public String doRedirect(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("userId", "ID001");
redirectAttributes.addFlashAttribute("userName", "mike");
redirectAttributes.addAttribute("flag", "opening");
return "redirect:../public/winOpenSucc.do";
} @RequestMapping(value = "/winOpenSucc.do")
public String redirectPage() {
return "redirect:../public/indexTest.jsp"
}
}
jsp页面
输出 url:http://lolcalhost:8080/project/page/public/indexTest?userId=ID001?userName=mike
here is indexTest.jsp
userId is
userName is
flag is
param_flag is opening
说明:二次重定向redirect后,前面的request生命周期结束,新的request由于model对象的注入,将flashmap中的参数转给新的request parameter,
此时${param.userId} ${param.userName}可以取到值
不足:暴露了敏感参数值,flashmap中的对象参数(如3.2的userInfo实例对象,受url不传对象的限制)及request parameter(flag)转发后消失
3.2跟踪model
controller
@Controller
@RequestMapping("/page/login")
public class LoginController { @RequestMapping(value = "/redirect.do")
public String doRedirect(RedirectAttributes redirectAttributes) {
User user=new User();
user.setMyId="ID002";
user.setMyName="lili";
redirectAttributes.addFlashAttribute("userId", "ID001");
redirectAttributes.addFlashAttribute("userName", "mike"); //将存入session falshmap中,request刷新后失,优点是隐藏具不用手动清理
redirectAttributes.addAttribute("flag", "opening");
return "redirect:../public/winOpenSucc.do"; //旧request消亡,将产生新的request,flag参数将存入新request中的parameter
} @RequestMapping(value = "/winOpenSucc.do")
public String redirectPage(Model model,HttpServletRequest request) {
System.out.println("print redirectpage controller model parameter:");
model.addAttribute("mdbefore", "before");
final Map map = model.asMap();
for (final Object obj : map.keySet()) {
System.out.println(obj.toString() + "==" + map.get(obj));
}
model.addAttribute("mdafter", "after"); System.out.println("print redirect controller request parameter:");
final Enumeration reqEnum = request.getParameterNames();
while (reqEnum.hasMoreElements()) {
final String s = (String) reqEnum.nextElement();
System.out.println(s + "==" + request.getParameter(s));
}
System.out.println("print redirect controller request attribute:");
final Enumeration reqAttrs = request.getAttributeNames();
while (reqAttrs.hasMoreElements()) {
final String s = (String) reqAttrs.nextElement();
System.out.println(s + "==" + request.getAttribute(s));
}
System.out.println("print redirect controller session parameter:");
final HttpSession session = request.getSession();
final Enumeration se = session.getAttributeNames();
while (se.hasMoreElements()) {
final String key = (String) se.nextElement();
System.out.println(key + "==" + session.getAttribute(key));
}
return "redirect:../public/indexTest.jsp"; //旧request(带falg参数)消亡,产生新的request(全新的,不带任何参数),model将自己的值注入新request.parameter中,并返回。
}
}
console
print redirectpage controller model parameter:
userInfo==com.xx.vdo.User@16675039 //此对象在redirect后,model注入新的request中时,消失
userId==ID001
userName==mike
mdbefore==before
print redirect controller request parameter: //后台第二个action中request 只有一个flag==opening参数
flag==opening
print redirect controller request attribute:
org.springframework.web.servlet.DispatcherServlet.INPUT_FLASH_MAP==FlashMap [attributes={userInfo=com.xx.vdo.User@16675039, userId=ID001,userName=mike}, targetRe
questPath=/ReportsTYKF/page/login/winOpenSucc.do, targetRequestParams={flag=[opening]}]
org.springframework.web.servlet.DispatcherServlet.FLASH_MAP_MANAGER==org.springframework.web.servlet.support.SessionFlashMapManager@c8398e7
org.springframework.web.servlet.DispatcherServlet.OUTPUT_FLASH_MAP==FlashMap [attributes={}, targetRequestPath=null, targetRequestParams={}]
print redirect controller session parameter:
jsp url:http://lolcalhost:8080/project/page/public/indexTest?userId=ID001&userName=mike&mdbefore=before&mdafter=after
jsp 中session,request打印结果:
page session parameter:
print redirectpage page request parameter: //此处已无flag==opning,参数个数为4,即model将值在第二次redirect后注入新的request.parameter中,
userId==ID001
userName==mike
mdbefore==before
mdafter==after
print redirectpage page request attribute:
4.完美实现flshmap参数安全,url地址改变,参数易存取。
其实2已经基本实现我们的需求,只是url没有变,如果我们要实现url的跳转,可以在jsp中增加代码。
前提:需求是外系统有一个菜单列表,点击后打开一个新窗口,跳转到本系统,并对连接进行安全检查,通过后相关信息存session,同时在页面初始化共公参数如操作员信息,同时做到不暴露敏感信息,最后进入本系统具体的页面。
<html>
<head>
<%
String id="bb11234";
//out.println("<script language='javascript'>window.location='"+"page/public/carList.jsp?reqId="+id+"';</script>");
%>
</head>
<body>
</body>
<script type="text/javascript">
//这里可以对共公变量进行初始化,然后再进行页面转发
project.userInfo.userId=${userInfo.myId};
project.userInfo.userName=${userInfo.myName};
project.current.operatorName=${userName};
var operatorId=${userId};
window.location="page/public/reportList.jsp?id="+operatorId;
</script >
<html>
后记:如果jsp发请求打开外系统新页面,只能选择window.open,或者form提交。需要解决跨域问题且格式不好控制。ajax发请求只能等返回信息然后再在本系统中打开页面。相当于至少两次请求。后面会再写一篇关于springMVC打开新页面springMVC接受json并打开新页面。
jsp取addFlashAttribute值深入理解即springMVC发redirect传隐藏参数的更多相关文章
- SpringMVC重定向(redirect)传参数,前端EL表达式接受值
由于重定向相当于2次请求,所以无法把参数加在model中传过去.在上面例子中,页面获取不到msg参数.要想获取参数,可以手动拼url,把参数带在后面.Spring 3.1 提供了一个很好用的类:Red ...
- 前台jquery+ajax+json传值,后台处理完后返回json字符串,如何取里面的属性值?(不用springmvc注解)
一.取属性值 前台页面: function select(id){ alert("hfdfhdfh"+id); $.ajax({ url:"selectByid.jsp& ...
- 属性成员是isXxx时对应的get方式是isXxx,前台jsp取不到这个属性值
最近在项目中无意设置的boolean变量值为isXxx,用eclipse生成相应的set和get方法,eclipse生成的的boolean类型的get方法为isXxx,前台导致取不到相应的值 publ ...
- php取默认值以及类的继承
(1)对于php的默认值的使用和C++有点类似,都是在函数的输入中填写默认值,以下是php方法中对于默认值的应用: <?phpfunction makecoffee($types = array ...
- javascript 如何访问 action或者controller 传给 jsp 页面的值
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...
- 在android的spinner中,实现取VALUE值和TEXT值。 ZT
在android的spinner中,实现取VALUE值和TEXT值. 为了实现在android的 spinner实现取VALUE值和TEXT值,我尝试过好些办法,在网上查的资料,都是说修改适配器, ...
- 在android的spinner中,实现取VALUE值和TEXT值
为了实现在android的spinner实现取VALUE值和TEXT值,我尝试过好些办法,在网上查的资料,都是说修改适配器,刚开始我也是通过修改适配器的方法来做的,但是如果一个activity有多个s ...
- java.sql.ResultSet技术(从数据库查询出的结果集里取列值)
里面有一个方法可以在查询的结果集里取出列值,同理,存储过程执行之后返回的结果集也是可以取到的. 如图: 然后再运用 java.util.Hashtable 技术.把取到的值放入(K,V)的V键值里,K ...
- 快速排序 之添加复合插入排序和原始序列取中值左pivot
quicksort中,当n小于一定值时,排序效率就比直接插入排序底了,所以,此时就不要再递归下去了,直接插入排序好了:快速的原理就是因为折半递归,所以初始pivot应该有个好一点的选择,这里在原序列左 ...
随机推荐
- Flask--异常处理
异常处理: abort(404)-捕获HTTP抛出的统一状态码 @app.errorhandler-捕获全局异常错误码,捕获异常错误 @app.route("/demo4") de ...
- nginx 隐藏 index.php
使用情景如下: 在访问 http://php.cc/Att/AttList 的时候.跳转到 http://php.cc/index.php/Att/AttList : 也就是开启重写功能: 在ngin ...
- C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)
但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...
- C++11--编译器生成的函数
using namespace std; class Dog {}; /* C++ 03 * 1 默认构造函数(只有当用户没有声明任何构造函数) * 2 拷贝构造(只有当用户没有声明5,6),扩展到C ...
- 峰Redis学习(8)Redis 持久化AOF方式
第三节:Redis 的持久化之AOF 方式 AOF方式:将以日志,记录每一个操作 优势:安全性相对RDB方式高很多: 劣势:效率相对RDB方式低很多: 1)AOF方式需要配置: # Please ...
- 学习笔记之Gurobi
Gurobi Optimization - The State-of-the-Art Mathematical Programming Solver http://www.gurobi.com/ind ...
- OpenVZ管理
查找内存超过5%,CPU超过10% CPU=${:-} MEM=${:-} for CTID in `vzlist|sed '1d'|awk '{print $1}'` { echo "== ...
- 开启BBR加速
在linux里用 wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh chmod +x b ...
- jdbi
JDBI是一个使用方便的SQL开发库,用符合Java语言习惯的集合.Bean等方式,提供关系数据库访问接口,同时保留了JDBC类似的信息.JDBI提供了链式和SQL两种风格的API. jdbi的网址是 ...
- [UE4]蓝图比C++慢10倍,是吗?
首先,蓝图肯定是比C++慢. 任何脚本语言(需要解释执行的语言),和C++相比可能达到十倍甚至百倍的差距.比如Java.Python.Lua,JS. 脚本语言是运行在虚拟机上的,所以它们比起直接运行的 ...