• SpringMVC


    2016-8-23修正。

    因为对modelattribute这个注解不了解,所以在网上搜寻一些答案,感觉还是似懂非懂的,所以便自己测试,同时还结合网上别人的答案;最后得出我自己的见解和结果,不知道正确否。同时还进行了一些注入参数的测试.下面的结果都是我自己测试得出来的,我也不能保证准确性,所以你发现有错误,欢迎指出。

    user是我创建的一个类,用于测试的,就几个常见的属性,如id username password startDate

    我看不懂springmvc的源码,但是我又很奇怪前台的数据是怎么绑定到controller参数上去的。然后我就自己通过代码去测试。

    Serlvet技术,前台的数据都是首先要传入httpservletrequest对象中,在springmvc中,也是一样,数据也是在HttpServletRequest中。

    SpringMVC,会帮我们创建ModelMap,他会用这个来帮我们管理,传递数据回jsp。

    比如前台请求url:http://localhost/LeranSpringMVC/setUser?username=abc&age=123&startDate=2015%2F1%2F2

    url中含有数据。如果在url对应的controller方法的参数中,能和传过来的数据名字对应,就会被springmvc绑定。

    比如:

    	public void setUser(User user ) {
    

      url中的数据,便会绑定到user中,因为user的属性Username password age 和url中数据的key对应。同时,user也会放入ModelMap

    如果modelmap中已经有了user,便会被覆盖。比如:

    	@ModelAttribute("user")
    	public User getUser() {
    		User user = new User();
    		user.setUsername("name");
    		user.setPassword("pass");
    		return user;
    	}
    
    
    //	System.out.println("modelAttribte注解的方法");
    	@RequestMapping("/setUser")
    	public void setUser(User user) {
    		 System.out.println("user = " + user);
    	}
    

      getUser方法被注解,那么在setUser被访问执行前会先执行。getUser会返回user放入modelmap。

    但是在setUser方法执行的时候,参数user会先去modelmap去找user,找到便绑定数据,然后如果前台还有user的数据传来,参数user的数据便会被覆盖,同时放入modelmap,覆盖之前的数据(是以一个个属性去覆盖的,我猜测是因为前台传来的是一个个的键值对)。

    注:只有在controller方法的参数中,有能在前台传过来的数据中找到对应的,那么这个前台数据才会被绑定到对应参数中,同时放入modelmap。

    比如上面的例子,前台传过来的数据会绑定到user中,同时放入modelmap。放入modelmap时的key是类名首字母小写。

    如果,controller方法,没有参数,或者没有能在前台数据找到对应的,那么modelmap中是没有数据的。

    注:modelmap中数据是request级别的。

    @ModelAttribute

    1.    modelattribute注解在方法的前面(方法前面加这个注解,那么在这个controller的其他方法被调用时,都必须要先执行这个方法。)

    作用:因为有modelattribute注解,会将方法返回的对象放入modelmap。

    如果被注解方法没有返回值,那么程序并不会报错,但是这样做没什么意思。比如:

    	@ModelAttribute
    	public void getUser() {
    	}
    	@ModelAttribute("user")
    	public void getUser() {
    	}
    

      

    如果注解后面没指定名字,就会将返回的类型名字,首字母小写作为key去存入modelmap。比如:

    	@ModelAttribute
    	public String getUser() {
    		return "abcd";
    	}
    

      modelmap中是   string = abcd

    如果注解后面跟(名字),那么返回的对象,放入modelmap时的key会是注解后面指定的名字。

    	@ModelAttribute("user")
    	public String getUser() {
    		return "abcd";
    	}
    

      modelmap中是  user = abcd

    2.  modelattribute注解在参数前面

    这样的注解,首先springmvc,会先去model找有没有user2这个对象,如果有,注入到user这个参数中(同时,如果前台还传过来user的属性对应的键值对,那么前面的user2会被覆盖),并且最后返回jsp的时候,user这个对象,会以名字user2放入作用域。

        public String test6(@ModelAttribute("user2") User user){
    

      

     3.  sessionAttributes和modelattribute 同时使用,而且名字一样,

    比如都是user2的话,那么modelAttributes会去session找user2,找不到就会报错。(如果没有user2的话,会报错,解决办法:创建一个方法,return new user,并且方法上面使用modelattribute注解。)

    如果找到了user2,就注入到user参数中(同时,如果user参数还被绑定了前台数据,那么会覆盖掉modelAttribute注入的数据)。

    最后的user会以user2的名字,放入session,而不是request作用域。

    @Controller
    @SessionAttributes("user2")
    public class UserController {
    
    
    	@ModelAttribute("user2")
    	public User getUser() {
    		User user = new User();
    		user.setUsername("name");
    		user.setPassword("pass");
    		return user;
    	}
    
    
    	@RequestMapping("/setUser")
    	public void setUser(@ModelAttribute("user2")User user2) {
    		 System.out.println("user = " + user2);
    	}
    

      

    SpringMVC注入参数

    springmvc在注入参数方面很智能。

    一般参数提交有 form表单提交方式和url后跟?加参数的形式。还有ajax提交的数据。(不论何种形式提交的参数,都是 名字 = 值,键值对的形式,springmvc就是根据key去进行匹配,匹配到进行注入

    如下面的这个代码测试。我发起请求,url是:http://localhost/springmvc/upload/test4?username=天气&password=123&str=aaaaa。

    测试结果是,username和password都注入到了user中,和str也对应的注入到了str中。

    注:这个测试中,我发现,对象user会被springmvc自动存入作用域request,而str这不会。

        @RequestMapping(value = "/test4")
        public String test4(User user,String str){
            user.setUsername("啊啊");
            System.out.println(str);
            return "upload";
        }
    

    就这个上面测试的结果,我感觉已经足够平时开发中的大多数提交参数的需求了。

    有时候比如,我们想隐藏后台真实参数的名字,就可以用注解@RequestParam来注入参数。

    如下代码测试,我请求的url是:http://localhost/springmvc/upload/test4?username=天天&password=123&min=1

    结果是:username和password都注入user了,min注入max了。   required的意思是,这个参数是否必须,如果是true的话,同时前台并没有传递这个参数,那么会报错。

        @RequestMapping(value = "/test4")
        public String test4(User user,@RequestParam(value = "min",required = true)String max){
            user.setUsername("啊啊");
            System.out.println(max);
            return "upload";
        }
    

      

    有时候,我们想让参数不要跟在?的后面,保持url链接的干净。就可以使用@PathVariable来注入参数

    如下代码测试,我请求的url是:http://localhost/springmvc/upload/test2/aaaaaa

    结果是,test2后面的值(aaaaaa)注入abc中。

    注:这个代码返回的页面上,有个${str},本来这个${str}是我做另外的测试用的,但是我发现在这个测试中,url中的值aaaaa,也同时放入了request中,在前台jsp页面是能够显示的。但是我在方法中通过request.getParameter和getAttribute尝试去取这个str,却显示结果为空。不明白springmvc是怎么做的。。。。。。  不过我还是需要记住这一点:PathVariable的值也会被放入作用域request中。

        @RequestMapping("/test2/{str}")
        public String test2(@PathVariable("str")String abc) {
            System.out.println(abc);
            return "upload";
        }
    

      

  • 相关阅读:
    ELK扫盲及搭建
    重构支付接口(二)重构方案
    重构支付接口(一)支付接口存在的问题
    redis的持久化(RDB与AOF)
    死锁、活锁、性能问题
    Android控件_RecycleView+CarView+Palette联合应用
    窗体间传值 ,子窗体传给父窗体
    【Android-自定义控件】 漂亮的Toast
    【Android-关闭所有Activity】关闭activity之前的所有activity,重启actibity
    【Android-自定义控件】SwipeRefreshDemo 下拉刷新,上拉加载
  • 原文地址:https://www.cnblogs.com/yanqin/p/5692583.html
Copyright © 2020-2023  润新知