springmvc 发送PUT 和 DELETE 请求

一: 发送 DELETE 或者 PUT 请求:

1、在表单中加入一个隐藏的参数: _method  , 值是 DELETE (或者PUT)

    <form action="springmvc/testRest/a1we2!3#d" method="post">
        <input type="hidden"  name="_method" value="DELETE"></input>
        <input type="submit" value="test Rest delete"></input>
    </form>

2、 发送的POST 请求, 配置一个 HiddenHttpMethodFilter 过滤器:

    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

该过滤器会把 获取 String paramValue = request.getParameter("_method");      

paramValue  值是 DELETE , 然后把该POST 的 HTTP请求的 改成 DELETE 请求。

 

3、在Controller 中匹配,获取上面的 DETELE 请求

        @RequestMapping(value="/testRest/{ss}", method=RequestMethod.DELETE)
        public String testRestDelete(@PathVariable("ss") String sid) {
            System.out.println("test DELETE: " + sid);
            return SUCCESS;
        }

输出: test DELETE: a1we2!3

点了 test Rest delete 这个按钮后,请求的url 是  http://localhost:8080/springmvc-1/springmvc/testRest/a1we2!3#d  , 在springmvc 中通过 PathVariable 注解获取 REST风格的URL 中的参数,获取的时候  ss 值是 a1we2!3 , 保存到 sid 中。 (把 # 后面的内容去掉了)

 

二:在 前台页面中写的链接:

<a href="springmvc/tsetParameters?username=zhou&age=11">tsetParameters</a></br>

  

RequestMapping 注解中可以使用 params 匹配请求中的参数, 用headers 匹配http请求中头域 

controller 方法中:
        @RequestMapping(value="tsetParameters", params={"username", "age!=10"},headers={"Accept-Language=zh-CN,zh;q=0.9" , "User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"})
        public String testParameters() {
            System.out.println("testParameters");
            return SUCCESS;
        }

当 前台发送的请求 是:  http://localhost:8080/springmvc-1/springmvc/tsetParameters?username=zhou&age=11 并且http 请求中带有:

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36

Accept-Language: zh-CN,zh;q=0.9

这两个头域的时候, 才会执行  testParameters 方法。

即执行 testParameters 方法需要同时满足以下的条件:

1、请求url  tsetParameters  中必须含有 username 参数,必须含有 age 参数 并且 值不能是 10.

2、请求header 中 必须有 Accept-Language 和 User-Agent 。 并且值是 RequestMapping 中写的。

否则就会报404 错误。

 

四: @RequestMapping 可以映射参数:

value 值即请求参数的参数名

required 该参数是否是必须,默认是true 。

defaultValue 请求参数的默认值

比如请求url: http://localhost:8080/springmvc-1/springmvc/testRequestParam?username=zhou

controller 方法:

        @RequestMapping(value="/testRequestParam")
        public String testRequestParam(@RequestParam(value="username") String name, @RequestParam(value="age",required=false, defaultValue="0") int age){
            System.out.println("name:" + name + "======" + "age:" + age);
            return SUCCESS;
        }

输出: name:zhou======age:0

 

RequestHeader 注解可以获取 http 请求的头域:
		@RequestMapping("/testHeader")
		public String testRequestHeader(@RequestHeader("User-Agent") String ua) {
			System.out.println(ua);
			return SUCCESS;
		}

  

CookieValue 可以获取cookie 值
		@RequestMapping("/testCookie")
		public String testCookieVal(@CookieValue("JSESSIONID") String cook) {
			System.out.println(cook);
			return SUCCESS;
		}

  

Servlet 原生API 作为目标方法的参数支持以下类型:

HttpServletRequest、HttpServletResponse、HttpSession、java.security.Principal、Local InputStream、 OutputStream、 Reader、Writer 。

		@RequestMapping("/testServletAPI")
		public void testServletAPI(HttpServletRequest  req, HttpServletResponse rep,Writer writer) throws IOException {
			System.out.println("HttpServletRequest:" + req + "--------" + rep);
			writer.write("this is servlet api");
		}

  前台页面上显示: this is servlet api

 

五:

springmvc 可以返回目标方法中的map对象:

Controller 方法:

		@RequestMapping("/testMap")
		public String testMap(Map<String, Object> map) {
			map.put("names", Arrays.asList("tim","jack","mike"));
			return SUCCESS;
		}

  在返回的页面 success.jsp 中 可以接收 names 对象:

<body>

  ${requestScope.names}
  ${names}

</body>

页面显示:

[tim, jack, mike] [tim, jack, mike]

 

Controller 层也可以返回 ModelAndView 对象:

        @RequestMapping("/testModelView")
        public ModelAndView testModel() {
            String viewName = SUCCESS;
            ModelAndView modelview = new ModelAndView(viewName);
            modelview.addObject("time",new Date());
            return modelview;
        }

success.jsp 通过  ${names}  或者 ${requestScope.names}  接收,在页面上显示时间。

 

六:

@sessionAttributes 可以通过属性名指定放到会话中的属性(value属性值), 也可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(types属性值)。

Controller 方法:

        @RequestMapping("/testSessionAttr")
        public String testSessionAttr(Map<String, Object> map) {
            User user = new User("tom","123","tomc@guigu.com", 20);
            map.put("userone", user);
            map.put("school", "qinghua");
            User user2 = new User("mike","365","mm@guigu.com", 30);
            map.put("usertwo2", user2.getAge());
       
return SUCCESS; }

需要在Controller 类上加上注解: @SessionAttributes(value={"userone"}, types={String.class})

user: ${userone} </br>                                                            在前台界面上取的值是: User [username=tom, password=123, email=tomc@guigu.com, age=20, address=null] 
request user: ${requestScope.userone} </br>                                                                User [username=tom, password=123, email=tomc@guigu.com, age=20, address=null] 
sessionScope user: ${sessionScope.userone}</br>                                                      User [username=tom, password=123, email=tomc@guigu.com, age=20, address=null]

school: ${school}</br>                                                                                                    qinghua
requestScope school: ${requestScope.school}</br>                                                      qinghua
sessoin school: ${sessionScope.school}</br>                                                                qinghua

usertwo: ${usertwo2}</br>                                                                                             30
requestScope usertwo: ${requestScope.usertwo2}</br>                                               30   
sessionScope usertwo: ${sessionScope.usertwo2}</br>                                               空

只有把 String 类型的值放到 session 中时, sessionScope 中才会取到。

 

七:

在前台页面向Controller传递bean 的属性时,如果bean 对象没有空的构造函数,并且前台页面传的属性和bean 的构造函数参数不匹配时,就会报错,没有空的构造函数:

严重: Servlet.service() for servlet [springmvc] in context with path [/springmvc-1] threw exception [Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zhou.entity.User]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.zhou.entity.User.<init>()] with root cause
java.lang.NoSuchMethodException: com.zhou.entity.User.<init>()
at java.lang.Class.getConstructor0(Class.java:2849)
at java.lang.Class.getDeclaredConstructor(Class.java:2053)

需要加上一个空的构造函数。

1、在方法定义上使用 @ModelAttribute 注解:SpringMVC 在调用Controller 目标处理方法前,会先逐个调用在方法级上标注了 @ModelAttribute 的方法。

2、在方法的入参前使用 @ModelAttribute 注解 ,可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数绑定到对象中,再传入入参,将方法入参对象添加到模型中

前台页面传入 username、email、 age:

    <form action="springmvc/testModeAttr">
        <input type="hidden" name="id" value="1">
        username: <input type="text" name="username" value="Tom"><br/>
        email: <input type="text" name="email" value="tomca@126.com"><br/>
        age: <input type="text" name="age" value="26"><br/>
        <input type="submit"  value="提交"><br/>
    </form>

Controller 中的方法:

        
        @RequestMapping("/testModeAttr")
        public String testModeAttr(User user,Map<String, Object> map) {
            System.out.println("modify:" + user);
            map.put("user", user);
            return SUCCESS;
        }
        
        @ModelAttribute
        public void getUser(@RequestParam(value="id", required=false) Integer id,Map<String, Object> map) {
            if(id!= null){
                User user = new User(1,"Tome", "12345","tom@guigu.com", 12);
                System.out.println("从数据库中获取的对象:" + user);
                map.put("user", user);
            }
        }

1、先执行 @ModelAttribute 注解的 getUser 方法, 输出: 从数据库中获取的对象:User [id=1, username=Tome, password=12345, email=tom@guigu.com, age=12]

把 user 存入 key是 user 的对象中。

2、 SpringMVC 把 从Map 中取出的 User 对象,并把表单的请求参数 赋给该 User 对象的对应属性。 (这一步是SpringMVC 完成的)  (在@ModelAttribute 修饰的方法中,放入到Map 时的键需要和目标方法入参类型的第一个字母小写的字符一致,)

      如果在 @ModelAttribute 修饰的方法中,map存入的对象 和 目标方法的参数类名的第一个字母小写的字符不一致,可以在目标方法中用 @ModelAttribute 修改该参数。 比如:

      

        @RequestMapping("/testModeAttr")
        public String testModeAttr(@ModelAttribute("usera") User user,Map<String, Object> map) {
            System.out.println("modify:" + user);
            map.put("user", user);
            return SUCCESS;
        }
        
        @ModelAttribute
        public void getUser(@RequestParam(value="id", required=false) Integer id,Map<String, Object> map) {
            if(id!= null){
                User user = new User(1,"Tome", "12345","tom@guigu.com", 12);
                System.out.println("从数据库中获取的对象:" + user);
                map.put("usera", user);
            }
        }

 则在 目标方法 testModeAttr 中的参数 user 也就是 map 中存入的 key 是 usera 的对象。

3、 再执行 目标方法 testModeAttr , 把上面的user 对象传入 该目标方法。

 

posted @ 2018-07-10 16:07  zhoudingzhao  阅读(7941)  评论(0编辑  收藏  举报