一、JSP传参到Controller
1、使用传统HttpServletRequest接收
- HttpServletRequest
- HttpServletResponse
- HttpSession
jsp code
<%--建议添加${pageContext.request.contextPath},每次从根目录发起请求,从而避免请求路径重复叠加--%>
<form action="${pageContext.request.contextPath}/user/login" method="post">
userame:<input name="username" type="text"><br/>
password:<input name="password" type="password"><br/>
<button type="submit">submit</button>
<button type="reset">reset</button>
</form>
java code
@Controller
@RequestMapping(path = "/user")//在类上修饰,提供理论初步的请求映射信息,相对于WEB的根目录
public class StudentController {
/**
*在方法上修饰,提供进一步的细分映射信息,相对于类定义处的url
*若类处未定义映射请求,则方法处标记的url相对于WEB的根目录
*/
@RequestMapping(path = "/login", method = RequestMethod.POST)
public void login(HttpServletRequest request){
System.out.println("username="+request.getParameter("username"));
System.out.println("password="+request.getParameter("password"));
}
}
2、使用参数直接获取
要求:函数参数名与请求参数名保持一致
@RequestMapping(value = "/login",method = RequestMethod.POST)
public void login(String username, String password){
System.out.println("username="+username);
System.out.println("password="+password);
}
<form action="${pageContext.request.contextPath}/login" method="post">
userame:<input name="username" type="text"><br/>
password:<input name="password" type="password"><br/>
<button type="submit">submit</button>
<button type="reset">reset</button>
</form>
3、通过POJO获取
要求:建立一个对象,属性名对应请求参数名保持一致,并生成相应的getter()和setter()方法
因为是反射技术,所以属性字段依然要保持完全一样
可以和方法2结合使用
pojo类:
public class User implements Serializable {
private String id;
private String name;
private String pwd;
private int age;
private boolean sex;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
......
public boolean isSex() { return sex; }
public void setSex(boolean sex) { this.sex = sex; }
}
@RequestMapping(value = "/login",method = RequestMethod.POST)
public void login(User u){
System.out.println("username="+u.getName());
System.out.println("password="+u.getPwd());
}
<form action="${pageContext.request.contextPath}/login" method="post">
userame:<input name="username" type="text"><br/>
password:<input name="password" type="password"><br/>
<button type="submit">submit</button>
<button type="reset">reset</button>
</form>
4、使用@RequestParam参数绑定获取
与方法2的使用方法类似,但是不限制参数名,可以绑定到自定义参数名上
//将jsp页面的name属性明文映射到controller方法的每一个参数上(方法参数名可以不同)
@RequestMapping(path = "/login", method = RequestMethod.POST)
public void login(@RequestParam("username") String name, @RequestParam("password") String pwd){
System.out.println("username="+name);
System.out.println("password="+pwd);
}
//将jsp页面的name属性映射到controller方法的参数上(jsp中的name要和接收的参数名字必须一致)
@RequestMapping(path = "/login", method = RequestMethod.POST)
public void login(@RequestParam(required=false) String username, String password){
System.out.println("username="+username);
System.out.println("password="+password);
}
value | 定义请求参数的名字 |
---|---|
required | 是否必须传入,默认是true,表示请求中一定要有相应的参数,否则会报错HTTP Status 400 - Required Integer parameter ‘XXX’ is not present |
defaultValue | 默认值,表示如果请求中没有此参数时的默认值 一般都把请求参数和形参定义成一样的,如果传进来的参数名称和对象中的属性名称一致则将参数值设置在pojo对象中。 |
5、将请求路径的可变参数传入方法@PathVariable
详情参考spring MVC(一)常用注解使用介绍(@PathVariable)
@RequestMapping(value="/user/view/{userId}", method=RequestMethod.GET)
private String viewUser(@PathVariable("userId") String userId){
return "user/view";
}
6、添加自定义Java类型的入参,并添加@ModelAttribute注解
@RequestMapping(value="/user/save", method=RequestMethod.POST)
private String doSave(@ModelAttribute User user, HttpSession session){
......
}
二、Controller传参到JSP
其返回值有三种类型
- ModelAndView
- String
- void
SpringMVC配置视图解析器:
会自动添加到返回的路径中,针对requestMapping中的路径不会添加
SpringMVC默认:InternalResourceViewResolver : 支持默认视图,采用forward,redirect。
视图名规则:不写前缀默认为"转发"
视图名字符串前缀:
forward:/xxx.jsp ->采用转发
redirect:/xxx.jsp ->采用重定向
注意:WEB-INF目录下的资源只能服务器级别访问,不能重定向访问的,详情请查看Web项目中关于WEB-INF目录的各种问题
设置视图路径的前后缀,该配置可以让我们写视图路径的时候更简单!!!
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--<property name="prefix" value="/jsps/" />-->
<property name="prefix" value="/WEB-INF/jsps/" />
<property name="suffix" value=".jsp" />
</bean>
下面表格都以设定了视图前后缀为前提:
- 明文声明forward \ redirect是不会被InternalResourceViewResolver拼接前后缀的
- 明文声明forward \ redirect如果不写文件后缀明,默认寻找controller映射路径
转发 | 转发到jsp | return "index"; return "user/showAll"; | 设定了视图前后缀,会自动拼接 |
---|---|---|---|
return "forward:/index.jsp"; | |||
转发到controller | return "forward:/user/showAll"; | ||
重定向 | 重定向到jsp | return "redirect:/index.jsp"; | 注意:重定向不能访问WEB-INF下的资源 |
重定向到controller | return "redirect:/user/showAll"; |
1、返回ModelAndView
看看下面几个事例体会一下
@RequestMapping("/data")
public ModelAndView demo(){
ModelAndView mav = new ModelAndView();//模型和视图对象
mav.addObject("data","数据:张三");//设置数据到前台
User u = new User();
u.setUsername("李四");
mav.addObject(u);//添加模型数据,key的值默认生成为对象的类型首字母小写 ex:User-->user
mav.setViewName("/test.jsp");//添加跳转的路径,默认为forward
return mav;
}
@RequestMapping(value = "/user/save", method = RequestMethod.POST)
public ModelAndView saveUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView("/user/save/result");//默认为forward模式
// ModelAndView mv = new ModelAndView("redirect:/user/save/result");//redirect模式
mv.addObject("message","保存用户成功!");
return mv;
}
要使用forward转发:只需把redirect换成forward即可,注意ModelAndView默认使用forward请求转发方式
1)不传递参数(转发/重定向)
/**
*forward转发方式
*/
public ModelAndView getPage404MV() {
ModelAndView mv = new ModelAndView("forward:/test.jsp");
mv..setViewName("forward:/test.jsp")//与上同理
mv..setViewName("/test.jsp")//与上同理
return mv;
}
=============================================================
/**
*redirect重定向方式
*/
public ModelAndView getPage404MV() {
ModelAndView mv = new ModelAndView("redirect:/404.html");
//ModelAndView mv = new ModelAndView("redirect:http://www.baidu.com");
return mv;
}
2)通过addObject()传值(转发)
添加视图前后缀为前提(InternalResourceViewResolver)
@RequestMapping(path = "/showAll",method = RequestMethod.POST)
public ModelAndView showAllStudent(){
List slist=studentService.getAllStudent();
ModelAndView mav=new ModelAndView();
mav.addObject("studentList",slist);
mav.addObject(slist);//添加模型数据,key的值默认生成为对象的类型首字母小写 ex:List-->list
mav.setViewName("show");//转发到/WEB-INF/jsps/show.jsp
return mav;
}
3)拼接URL带参传递(重定向)
/**
*手动拼接url进行参数传递,这样有个弊端,就是传中文可能会有乱码问题
*/
@RequestMapping(path = "/showAll")
public ModelAndView showAllStudent(){
return new ModelAndView("redirect:/user/toList?param1="+1+"¶m2="+2);
}
2、返回String
1)不传递参数(转发/重定向)
/*
* 请求转发(forward):
* Url地址不会改变
*/
@RequestMapping("/data2")
public String demo2(Model model,HttpSession session){
return "forward:/test.jsp";//-->相当于手动指定了跳转的路径
}
=====================================================================
/*
* 重定向(redirect):
* url地址会改变
*/
@RequestMapping("/data3")
public String demo3(Model model,HttpSession session){
return "redirect:/test.jsp";
}
2)通过Model传递参数(转发/重定向)
/*
* 使用Model方式
*/
@RequestMapping("/data1")
public String demo1(Model model){
model.addAttribute("data","数据:李四");//设置数据到前台
User u = new User();
u.setUsername("张三");
//添加模型数据,key的值为对象的类型首字母小写 ex:User-->user
model.addAttribute(u);
return "test.jsp";
}
/*
* 请求转发(forward):
* 上面案例是转发,转发的值都是放到request请求作用域,下一个页面可以取出
* Url地址不会改变
*/
@RequestMapping("/data2")
public String demo2(Model model,HttpSession session){
model.addAttribute("data", "数据:使用model传递");//可以取出数据
User u = new User();
u.setUsername("张三");
model.addAttribute(u);
session.setAttribute("s", u);//可以取出数据
//return "/test.jsp";//返回路径
return "forward:/test.jsp";//-->相当于手动指定了跳转的路径
}
/*
* 重定向(redirect):
* 重定向就是发出一个全新的请求,
* 如果把值放到request请求,下一个页面不能取出
* 如果把值放到session会话请求,下一个页面可以取出
* url地址会改变
*/
@RequestMapping("/data3")
public String demo3(Model model,HttpSession session){
// model.addAttribute("data","张三");//不可以取出数据
session.setAttribute("s", "张三session");//可以取出数据
return "redirect:/test.jsp";
}
3)RedirectAttributes对象传递(重定向)
方法 | 区别 |
addAttribute() | 传递参数会自动拼接在URL后面 ,如:http:/index.action?a=a |
addFlashAttribute() | 不会跟随在URL后面,会把该参数值暂时保存于session在跳到页面后马上移除对象。所以你刷新一下后这个值就会丢掉 |
1.addAttribute方法传递参数会跟随在URL后面
这样在toController这个方法中就可以通过获得参数的方式获得这个参数,再传递到页面。过去的url和直接手动拼接是一样的。
@RequestMapping("/save")
public String save(@ModelAttribute("form") Bean form,RedirectAttributes attr)
throws Exception {
String value="aaa";
attr.addAttribute("param", value);
return "redirect:/namespace/toController";
}
2.addFlashAttribute不会跟随在URL后面
会把该参数值暂时保存于session,待重定向url获取该参数后从session中移除,这里的redirect必须是方法映射路径,jsp无效。你会发现redirect后的jsp页面中b只会出现一次,刷新后b再也不会出现了,这验证了上面说的,b被访问后就会从session中移除。对于重复提交可以使用此来完成.
@RequestMapping("/save")
public String save(@ModelAttribute("form") Bean form,RedirectAttributes attr)
throws Exception {
String code = service.save(form);
if(code.equals("000")){
attr.addFlashAttribute("name", form.getName());
attr.addFlashAttribute("success", "添加成功!");
return "redirect:/index";
}else{
attr.addAttribute("projectName", form.getProjectName());
attr.addAttribute("enviroment", form.getEnviroment());
attr.addFlashAttribute("msg", "添加出错!错误码为:"+rsp.getCode().getCode()+",错误为:"+rsp.getCode().getName());
return "redirect:/maintenance/toAddConfigCenter";
}
}
@RequestMapping("/index")
public String save(@ModelAttribute("form") Bean form,RedirectAttributes attr)
throws Exception {
return "redirect:/main/list";
}
3、返回void
使用传统HttpServletRequest 、HttpServletResponse
@RequestMapping("/data")
public void demo(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
request.setAttribute("data", "数据:hello");
request.getRequestDispatcher("test.jsp").forward(request, response);
}
三、controller跳转到controller
明文显示 forward、redirect 默认都会跳转到controller(不写文件后缀的前提下),添加了InternalResourceViewResolver,也不会拼接profix、suffer
写法如下:
return "forward:aaaa/bbbb";
return "redirect:aaaa/bbbb";
return new ModelAndView("forward:bbbb", null);
return new ModelAndView("redirect:bbbb", null);
使用时注意对 “/” 的应用
开头是否添加/ | 事例 | 描述 |
---|---|---|
YES | forward:/aaaa redirect:/aaaa | 绝对路径,从根目录开始 |
NO | forward:aaaa redirect:aaaa | 相对路径,从当前请求开始(可能出现请求拼接的情况) |
web.xml
<!--配置Spring MVC的前端控制器:DispatcherServlet-->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--SpringMVC配置文件路径和文件名称设定-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<!--web应用启动时立即加载-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
spring-servlet.xml
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>