结论:两种方式

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传隐藏参数的更多相关文章

  1. SpringMVC重定向(redirect)传参数,前端EL表达式接受值

    由于重定向相当于2次请求,所以无法把参数加在model中传过去.在上面例子中,页面获取不到msg参数.要想获取参数,可以手动拼url,把参数带在后面.Spring 3.1 提供了一个很好用的类:Red ...

  2. 前台jquery+ajax+json传值,后台处理完后返回json字符串,如何取里面的属性值?(不用springmvc注解)

    一.取属性值 前台页面: function select(id){ alert("hfdfhdfh"+id); $.ajax({ url:"selectByid.jsp& ...

  3. 属性成员是isXxx时对应的get方式是isXxx,前台jsp取不到这个属性值

    最近在项目中无意设置的boolean变量值为isXxx,用eclipse生成相应的set和get方法,eclipse生成的的boolean类型的get方法为isXxx,前台导致取不到相应的值 publ ...

  4. php取默认值以及类的继承

    (1)对于php的默认值的使用和C++有点类似,都是在函数的输入中填写默认值,以下是php方法中对于默认值的应用: <?phpfunction makecoffee($types = array ...

  5. javascript 如何访问 action或者controller 传给 jsp 页面的值

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  6. 在android的spinner中,实现取VALUE值和TEXT值。 ZT

    在android的spinner中,实现取VALUE值和TEXT值.   为了实现在android的 spinner实现取VALUE值和TEXT值,我尝试过好些办法,在网上查的资料,都是说修改适配器, ...

  7. 在android的spinner中,实现取VALUE值和TEXT值

    为了实现在android的spinner实现取VALUE值和TEXT值,我尝试过好些办法,在网上查的资料,都是说修改适配器,刚开始我也是通过修改适配器的方法来做的,但是如果一个activity有多个s ...

  8. java.sql.ResultSet技术(从数据库查询出的结果集里取列值)

    里面有一个方法可以在查询的结果集里取出列值,同理,存储过程执行之后返回的结果集也是可以取到的. 如图: 然后再运用 java.util.Hashtable 技术.把取到的值放入(K,V)的V键值里,K ...

  9. 快速排序 之添加复合插入排序和原始序列取中值左pivot

    quicksort中,当n小于一定值时,排序效率就比直接插入排序底了,所以,此时就不要再递归下去了,直接插入排序好了:快速的原理就是因为折半递归,所以初始pivot应该有个好一点的选择,这里在原序列左 ...

随机推荐

  1. 运行startup.bat的启动过程

    一.前言 一般启动tomcat都是找到bin目录下的startup.bat(windows)下或者startup.sh(linux下),所以要研究tomcat的启动,startup脚本是避不开的.那么 ...

  2. SELinux杂谈

    ----------------------------- 文末有推荐参考文档列表--------------------------- SELinux(Security Enhanced Linux ...

  3. 学习使用NotePad++

    参考使用Notepad的快捷键: http://www.cnblogs.com/jungege/p/6003992.html ================================== 实用 ...

  4. 【springBoot】之概述

    springboot是什么? springboot不是对spring的增强,而是一个快速使用spring进行开发的框架. 其产生的背景是因为随着动态语言(Scala,Groovy)的流行,Java语言 ...

  5. 服务容错保护断路器Hystrix之八:Hystrix资源隔离策略

    在一个基于微服务的应用程序中,您通常需要调用多个微服务完成一个特定任务.不使用舱壁模式,这些调用默认是使用相同的线程来执行调用的,这些线程Java容器为处理所有请求预留的.在高服务器请求的情况下,一个 ...

  6. Consul之:key/value存储

    key/value作用 动态修改配置文件 支持服务协同 建立leader选举 提供服务发现 集成健康检查 除了提供服务发现和综合健康检查,Consul还提供了一个易于使用的键/值存储.这可以用来保存动 ...

  7. JVM异常之:方法区溢出OutOfMemoryError: PermGen space

    1.方法区溢出(Perm持久代溢出) 在jdk1.6及之前的版本中,常量池放在Perm区也即是方法区中,所以在jdk1.6版本中,常量池溢出可以说是方法区溢出. 示例一: 方法区溢出的示例见<J ...

  8. maven使用笔记--在父pom中声明过的jar可以被继承,使子项目不用写版本号由父pom控制

    将dependencies放到dependencyManagement中,如下: [html] view plaincopy <dependencyManagement> <depe ...

  9. [UE4]死亡后调整视角

    AddLocalOffset:本地坐标偏移. 脱离控制器操作 会影响“OnDie”方法里面的相机移动操作,而函数里面又不允许使用“Delay”方法,但可以使用“Set Timer By Functio ...

  10. window.open打开新窗口报错ie 位指明错误,原因是window没有加引号!

    function JsMod(htmlurl,tmpWidth,tmpHeight){ htmlurl=getRandomUrl(htmlurl); var newwin = window.open( ...