spring MVC(二)数据传递

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fox_bert/article/details/88815570

一、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+"&param2="+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方式
    */
    @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>

猜你喜欢

转载自blog.csdn.net/fox_bert/article/details/88815570