157_SpringBoot_web请求参数处理

举报
alexsully 发表于 2021/09/22 20:06:07 2021/09/22
【摘要】 参数请求处理

1 rest使用与原理
@xxxMapping;
Rest风格支持(使用HTTP请求方式动词来表示对资源的操作)
以前:/getUser获取用户     /deleteUser删除用户    /editUser修改用户 /saveUser保存用户
现在: /user GET-获取用户  DELETE-删除用户 PUT-修改用户  POST-保存用户
核心Filter;HiddenHttpMethodFilter
用法: 表单method=post,隐藏域 _method=put

index表单

      测试REST风格;
        <form action="/user" method="get">
            <input value="REST-GET 提交" type="submit"/>
        </form>
        <form action="/user" method="post">
            <input value="REST-POST 提交" type="submit"/>
        </form>
        <form action="/user" method="post">
            <input name="_method" type="hidden" value="delete"/>
            <input name="_m" type="hidden" value="delete"/>
            <input value="REST-DELETE 提交" type="submit"/>
        </form>
        <form action="/user" method="post">
            <input name="_method" type="hidden" value="PUT"/>
            <input value="REST-PUT 提交" type="submit"/>
        </form>

controller

@RestController
public class HelloController {
    
    //    @RequestMapping(value = "/user",method = RequestMethod.GET)
    @GetMapping("/user")
    public String getUser(){

        return "GET-alex";
    }

    //    @RequestMapping(value = "/user",method = RequestMethod.POST)
    @PostMapping("/user")
    public String saveUser(){
        return "POST-alex";
    }


    //    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    @PutMapping("/user")
    public String putUser(){

        return "PUT-alex";
    }

    @DeleteMapping("/user")
//    @RequestMapping(value = "/user",method = RequestMethod.DELETE)
    public String deleteUser(){
        return "DELETE-alex";
    }
}

SpringBoot中手动开启 (扩展:如何把_method 这个名字换成自定义名字)

@Configuration(proxyBeanMethods = false)
public class WebConfig {
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
        HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
        methodFilter.setMethodParam("_m");
        return methodFilter;
    }

}

Rest原理(表单提交要使用REST的时候)
表单提交会带上_method=PUT
请求过来被HiddenHttpMethodFilter拦截
请求是否正常,并且是POST
获取到_method的值。
兼容以下请求;PUT.DELETE.PATCH
原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。

   @Bean
    @ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
    @ConditionalOnProperty(
        prefix = "spring.mvc.hiddenmethod.filter",
        name = {"enabled"}
    )
    public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new OrderedHiddenHttpMethodFilter();
    }

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);
    }

Rest使用客户端工具,如PostMan直接发送Put、delete等方式请求,无需Filter

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。