当前位置: 移动技术网 > IT编程>开发语言>Java > SpringMVC 自定义参数解析器.

SpringMVC 自定义参数解析器.

2019年11月22日  | 移动技术网IT编程  | 我要评论
一、简述 有没有想过像 @RequestParam、@RequestBody 这些注解的工作原理呢?为什么 form 表单、application/json 的参数能够直接封装进 Bean 对象中呢?这就要说到 HandlerMethodArgumentResolver — 方法参数解析器,该接口有 ...

一、简述

有没有想过像 @requestparam、@requestbody 这些注解的工作原理呢?为什么 form 表单、application/json 的参数能够直接封装进 bean 对象中呢?这就要说到 handlermethodargumentresolver — 方法参数解析器,该接口有两个方法:

public interface handlermethodargumentresolver {

    boolean supportsparameter(methodparameter parameter);


    object resolveargument(methodparameter parameter, modelandviewcontainer mavcontainer,
            nativewebrequest webrequest, webdatabinderfactory binderfactory) throws exception;

}

supportsparameter 方法返回 boolean 值,表示是否启用该解析器,true 表示启用,false 表示不启用;resolveargument 方法表示方法参数的解析过程,就是你把 http 的请求参数转换为方法参数的过程,返回 object 对象,即参数的转换结果。

@requestparam 对应的参数解析器是 requestparammethodargumentresolver;@requestbody 对应的参数解析器是 requestresponsebodymethodprocessor;诸如此类的解析器,读者可自行阅读。

二、自定义参数解析器

我想在控制器方法参数中得到当前用户的登陆信息,大概是如下这个效果,只要添加了 @currentuser 注解,那么 userparam 参数中就会有当前用户的登陆信息。

    @requestmapping(value = "/list", method = requestmethod.post)
    public responsedata<list<syswaydto>> list(@currentuser userparam userparam) {
        map<string, object> objectmap = maputils.convertobjtomap(userparam);
        return syswayservice.findwithorigindest(objectmap);
    }

怎么实现呢?首先我们需要有一个 @currentuser 注解:

@target(elementtype.parameter)
@retention(retentionpolicy.runtime)
public @interface currentuser {
}

那么剩下来的工作就是 handlermethodargumentresolver 的事情了:

@slf4j
public class currentuserhandlermethodargumentresolver implements handlermethodargumentresolver {

    /**
     * 用于判定是否需要处理该参数分解,返回 true 为需要,并会去调用下面的方法resolveargument。
     */
    @override
    public boolean supportsparameter(methodparameter methodparameter) {
        return methodparameter.getparametertype().isassignablefrom(userparam.class)
                && methodparameter.hasparameterannotation(currentuser.class);
    }

    /**
     * 真正用于处理参数分解的方法,返回的 object 就是 controller 方法上的形参对象。
     */
    @override
    public object resolveargument(methodparameter methodparameter, modelandviewcontainer modelandviewcontainer, nativewebrequest nativewebrequest, webdatabinderfactory webdatabinderfactory) throws exception {
        string accesstoken = nativewebrequest.getheader(gatewayheader.accesstoken);
        try {
            userparam userparam = jsonutils.readvalue(jwthelper.parsejwt(accesstoken), userparam.class);
            return userparam ;
        } catch (ioexception e) {
            log.error("currentuserhandlermethodargumentresolver resolveargument readvalue error.accesstoken:{}", accesstoken, e);
        } catch (exception e) {
            log.error("currentuserhandlermethodargumentresolver resolveargument error.accesstoken:{}", accesstoken, e);
        }
        return null;
    }
}

最后,别忘了注册上自定义的参数解析器哦!

@configuration
public class webconfig extends webmvcconfigureradapter {

    @override
    public void addargumentresolvers(list<handlermethodargumentresolver> argumentresolvers) {
        argumentresolvers.add(new currentuserhandlermethodargumentresolver());
    }
}

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网