1、@PathVariable
@PathVariable:映射URL绑定的占位符。
适用REST。
package com.xianhuii; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/springmvc") public class RequestMappingTest01 { private static final String SUCCESS = "success"; @RequestMapping("/testPathVariable/{id}") public String testPathVariable(@PathVariable("id") Integer id) { System.out.println(id); return SUCCESS; } }
2、REST
REST(Representational State Transfer):(资源)表现层状态转化。
资源(Resources):网络上的一个实体,每种资源对应一个特定的URI。
表现层(Representation):把资源具体呈现出来的形式。
状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议是一种无状态的协议,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,就必须通过某种手段,让服务器端发生“转台转化”(State Transfer)。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别敌营四种基本操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。
/order/1 GET:获取id=1的order /order/1 DELETE:删除id=1的order /order/1 PUT:更新id=1的order /order POST:新增order
3、HiddenHttpMethodFilter过滤器
HiddenHttpMethodFilter:将POST请求转为DELETE、PUT请求。
源码:
package org.springframework.web.filter; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import org.springframework.http.HttpMethod; import org.springframework.util.Assert; import org.springframework.util.StringUtils; public class HiddenHttpMethodFilter extends OncePerRequestFilter { private static final List<String> ALLOWED_METHODS; public static final String DEFAULT_METHOD_PARAM = "_method"; private String methodParam = "_method"; public HiddenHttpMethodFilter() { } public void setMethodParam(String methodParam) { Assert.hasText(methodParam, "'methodParam' must not be empty"); this.methodParam = methodParam; } protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { HttpServletRequest requestToUse = request; if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) { String paramValue = request.getParameter(this.methodParam); if (StringUtils.hasLength(paramValue)) { String method = paramValue.toUpperCase(Locale.ENGLISH); if (ALLOWED_METHODS.contains(method)) { requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method); } } } filterChain.doFilter((ServletRequest)requestToUse, response); } static { ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name())); } private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper { private final String method; public HttpMethodRequestWrapper(HttpServletRequest request, String method) { super(request); this.method = method; } public String getMethod() { return this.method; } } }
配置(web.xml):
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置HidenHttpMethodFilter:将POST请求转为DELETE、PUT请求--> <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> </web-app>
前端:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <%--GET--%> <a href="/springmvc/testRest/1">testRest1</a><br> <%--POST--%> <form action="/springmvc/testRest" method="post"> <input type="submit" value="testRest POST"> </form> <%--DELETE--%> <form action="/springmvc/testRest/1" method="post"> <input type="hidden" name="_method" value="DELETE"> <input type="submit" value="testRest DELETE"> </form> <%--PUT--%> <form action="/springmvc/testRest/1" method="post"> <input type="hidden" name="_method" value="PUT"> <input type="submit" value="testRest PUT"> </form> </body> </html>
Controller:
package com.xianhuii; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/springmvc") public class RequestMappingTest01 { private static final String SUCCESS = "success"; @RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET) public String testRestGet(@PathVariable("id") Integer id) { System.out.println("get" + id); return SUCCESS; } @RequestMapping(value = "/testRest/", method = RequestMethod.POST) public String testRestPost() { System.out.println("POST"); return SUCCESS; } @RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE) //@ResponseBody public String testRestDelete(@PathVariable("id") Integer id) { System.out.println("DELETE" + id); return SUCCESS; } @RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT) //@ResponseBody public String testRestPut(@PathVariable("id") Integer id) { System.out.println("PUT" + id); return SUCCESS; } }
4、@RequestParam
SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法相应的形参中。
SpringMVC对控制器处理方法签名的限制是很宽松的,几乎可以按照喜欢的任何方法对方法进行签名。
必要是可以对方法、方法形参标注相应的注解:@PathVariable、@RequestParam、@RequestHeader等。SpringMVC会将HTTP请求的信息绑定到相应的方法形参中,并根据方法的返回值类型作出相应的后续处理。
package com.xianhuii; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller @RequestMapping("/springmvc") public class RequestMappingTest01 { private static final String SUCCESS = "success"; /** * @RequestParam映射请求参数: * value:请求参数的参数名 * required:该参数是否必须,默认为true * defaultValue:请求参数的默认值 * @param name * @param age * @return */ @RequestMapping("/testRequestParam") public String testRequestParam( @RequestParam(value = "username", required = false) String name, @RequestParam(value = "age", required = false, defaultValue = "0") int age) { System.out.println("username: " + name + ", age: " + age); return SUCCESS; } }
5、@RequestHeader
映射请求头信息。
package com.xianhuii; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller @RequestMapping("/springmvc") public class RequestMappingTest01 { private static final String SUCCESS = "success"; @RequestMapping("/testRequestHeader") public String testRequestHeader(@RequestHeader("Accept-Language") String val) { System.out.println("testRequestHeader: " + val); return SUCCESS; } }
6、@CookieValue
绑定请求中的Cookie值。
package com.xianhuii; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller @RequestMapping("/springmvc") public class RequestMappingTest01 { private static final String SUCCESS = "success"; /** * @CookieValue:映射一个Cookie值。 * @param sessionId * @return */ @RequestMapping("testCookieValue") public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) { System.out.println("testCookieValue: " + sessionId); return SUCCESS; } }
7、使用POJO对象绑定请求参数值
SpringMVC会按照请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。
POJO(User):
package com.xianhuii.entities; public class User { private String username; private String password; private String email; private int age; private Address address; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + ", age=" + age + ", address=" + address + '}'; } }
POJO(Address):
package com.xianhuii.entities; public class Address { private String province; private String city; public String getProvince() { return province; } public void setProv***ring province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "Address{" + "province='" + province + '\'' + ", city='" + city + '\'' + '}'; } }
前端:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <form action="/springmvc/testPOJO" method="post"> <p>username: <input type="text" name="username"></p> <p>password: <input type="password" name="password"></p> <p>email: <input type="text" name="email"></p> <p>age: <input type="text" name="age"></p> <p>city: <input type="text" name="address.city"></p> <p>province: <input type="text" name="address.province"></p> <p><input type="submit" value="Submit"></p> </form> </body> </html>
Controller:
package com.xianhuii; import com.xianhuii.entities.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller @RequestMapping("/springmvc") public class RequestMappingTest01 { private static final String SUCCESS = "success"; @RequestMapping("/testPOJO") public String testPojo(User user) { System.out.println(user); return SUCCESS; } }
8、使用Servlet API作为形参
package com.xianhuii; import com.xianhuii.entities.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Controller @RequestMapping("/springmvc") public class RequestMappingTest01 { private static final String SUCCESS = "success"; /** * 可以使用Servlet原生API作为目标方法的参数: * HttpServletRequest * HttpServletResponse * HttpSession * java.security.Principal * Locale * InputStream * OutputStream * Reader * Writer * @param request * @param response * @return */ @RequestMapping("/testServletAPI") public String testServletAPI(HttpServletRequest request, HttpServletResponse response) { return SUCCESS; } }