请求映射
Rest风格(使用HTTP请求方式动词来表示对资源的操作)
/user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户 在index.html中添加表单标签:<form action="/user" method="post">
<input value="REST-post test" type="submit">
</form>
<form action="/user" method="get">
<input value="REST-get test" type="submit">
</form>
<form action="/user" method="delete">
<input value="REST-delete test" type="submit">
</form>
<form action="/user" method="put">
<input value="REST-put test" type="submit">
</form>
我们会发现method属性中只有post和get两个值,但是我们先按照Rest风格的格式进行赋值。
在HelloController.java中编写对应处理方法
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getUser(){
return "GET-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.POST)
public String saveUser(){
return "POST-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.PUT)
public String putUser(){
return "PUT-张三";
}
@RequestMapping(value = "/user",method = RequestMethod.DELETE)
public String deleteUser(){
return "DELETE-张三";
}
进入网站测试,依次点击四个测试按钮发现前两个使用post和get方法的结果正确,后两个方法的显示结果错误。原因是后两个方法目前不支持,所以直接按照默认值get执行,为了解决这个问题,我们不妨再次看一下源码:仍在是在WebMvcAutoConfiguration.class
这个类下方寻找,找到一个名为public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter()
的方法,我们可以通过这个过滤器启用Rest风格,同时也说明springboot是默认配置这个过滤器的。再查看OrderedHiddenHttpMethodFilter
的源码,发现是HiddenHttpMethodFilter
这个类的子类,继续向深层找,找到这个类的源码
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 HttpMethodRequestWrapper(request, method);
}
}
}
filterChain.doFilter((ServletRequest)requestToUse, response);
}
我们发现最外层判断条件是当method的值为POST时才生效,String paramValue = request.getParameter(this.methodParam);
这句意思是获取名为methodParam的值。观察上文发现methodParam被规定了值:private String methodParam = "_method";
也就是说我们需要在form标签中添加一个名为_method
的隐藏域,这个隐藏域的值则是我们希望该form标签生效的Rest风格。修改delete和put两个风格的form表单:
<form action="/user" method="post">
<input type="hidden" name="_method" value="DELETE">
<input value="REST-delete test" type="submit">
</form>
<form action="/user" method="post">
<input type="hidden" name="_method" value="PUT">
<input value="REST-put test" type="submit">
此时我们再次执行测试发现仍然没有生效,于是我们再去查看源码:发现在WebMvcAutoConfiguration.class
这个类下的public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter()
方法的注释有所要求:
@Bean
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
@ConditionalOnProperty(
prefix = "spring.mvc.hiddenmethod.filter",
name = {"enabled"}
)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
这两个@Conditional注解表示如果开发者没有配置HiddenHttpMethodFilter.class
这个类则springboot会自动配置,重点在后面这个@Conditional注解,我们只有配置了规定的属性这个过滤器才会生效。如果没有配置该属性则默认不生效,那么我们需要在yaml文件中进行配置。
spring:
mvc:
hiddenmethod:
filter:
enabled: true
开启过滤器后我们再进行测试发现功能正常,配置成功。
Rest原理(表单提交要使用REST的时候)
- 表单提交会带上_method=PUT
- 请求过来被HiddenHttpMethodFilter拦截
- 请求是否正常,并且是POST
- 获取到_method的值。
- 兼容以下请求;PUT.DELETE.PATCH
- 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
- 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。
我们可以直接在Controller类使用四种Rest风格的注解:
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
注意:使用这四种注解也需要开启过滤器
标签:11,String,request,Rest,日记,public,POST,method,springboot From: https://www.cnblogs.com/tarorat/p/17113369.html