栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何通过提供仅POST的@Valid删除冗余的Spring MVC方法?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何通过提供仅POST的@Valid删除冗余的Spring MVC方法?

如果您查看spring如何解决传递给处理程序的参数,那么实现自己所需的功能并不难。默认情况下,spring将使用

ModelAttributeMethodProcessor
带有
@ModelAttribute
和简单类型注释的for参数。

只看

ModelAttributeMethodProcessor.supportsParameter()
方法实现。

@Overridepublic boolean supportsParameter(MethodParameter parameter) {    if (parameter.hasParameterAnnotation(ModelAttribute.class)) {        return true;    }    else if (this.annotationNotRequired) {        return !BeanUtils.isSimpleProperty(parameter.getParameterType());    }    else {        return false;    }}

ModelAttributeMethodProcessor
如果
@Valid
找到了注释,它还负责启动验证。它以一种有趣的方式执行此操作,以使代码无需
@Valid
在类路径上即可进行编译。幸运的是,这很容易利用您的优势。

提取

ModelAttributeMethodProcessor.validateIfApplicable() method.

protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {    Annotation[] annotations = parameter.getParameterAnnotations();    for (Annotation annot : annotations) {        if (annot.annotationType().getSimpleName().startsWith("Valid")) { Object hints = AnnotationUtils.getValue(annot); binder.validate(hints instanceof Object[] ? (Object[]) hints : new Object[] {hints}); break;        }    }}

您可能已经注意到,它只是检查在参数开头是否存在注释,

"Valid"
并告诉绑定程序验证其值。

编写自定义注释

首先要做的是编写一个新的注释,您的自定义

HandlerMethodArgumentResolver
将支持该注释。

/@Target({ PARAMETER })@Retention(RUNTIME)public @interface ValidModifyingVerb {}

请注意,注释的名称故意以开头

"Valid"

推出自己的
HandlerMethodArgumentResolver

最简单的方法是扩展

ModelAttributeMethodProcessor
和修改其行为。由于该
resolveArgument()
方法是
最终 方法,因此无法覆盖它。我们可以做的是重写以下三种方法:

  1. supportsParameter(final MethodParameter parameter)

告诉spring这个解析器支持参数用注释

@ValidModifyingVerb

  1. bindRequestParameters(final WebDataBinder binder, final NativeWebRequest request)

将是获得对请求的引用并查找其请求方法的理想人选。它还使您有机会在不需要时省略绑定参数。

  1. validateIfApplicable(final WebDataBinder binder, final MethodParameter parameter)

使您有机会省略验证。如果您需要验证,由于您自己的注释开头

"Valid"
很好,因此它将被自动提取。

实现以上内容将导致类似于此的类。

public class ValidModifyingVerbMethodArgumentResolver extends ModelAttributeMethodProcessor {    private String requestMethod;        public ValidModifyingVerbMethodArgumentResolver(final boolean annotationNotRequired) {        super(annotationNotRequired);    }    @Override    public boolean supportsParameter(final MethodParameter parameter) {        return super.supportsParameter(parameter) && parameter.hasParameterAnnotation(ValidModifyingVerb.class);    }    @Override    protected void bindRequestParameters(final WebDataBinder binder, final NativeWebRequest request) {        HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);        requestMethod = servletRequest.getMethod();        if (isModifyingMethod(requestMethod)) { ((ServletRequestDataBinder) binder).bind(servletRequest);        }    }    @Override    protected void validateIfApplicable(final WebDataBinder binder, final MethodParameter parameter) {        if (isModifyingMethod(requestMethod)) { super.validateIfApplicable(binder, parameter);        }    }    private boolean isModifyingMethod(String method) {        return !"GET".equals(method);    }}

剩下的唯一事情就是

ValidModifyingVerbMethodArgumentResolver
在应用程序上下文配置中注册为参数解析器,然后就完成了。

public class ApplicationConfiguration extends WebMvcConfigurerAdapter {    @Override    public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> argumentResolvers) {        argumentResolvers.add(new ValidModifyingVerbMethodArgumentResolver(true));    }}

现在可以将控制器中的处理程序方法简化为:

@RequestMapping("/account/register")public String registerPost(        @ValidModifyingVerb RegisterForm registerForm,        BindingResult result,        RedirectAttributes redirectAttributes) {    //... ADD USER HERE IF !result.hasErrors() ...    return "account/register";}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/382345.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号