专栏首页后端沉思录自定义参数解析器

自定义参数解析器

开发中,app端给服务端会传基础参数、其他参数,一般基础参数app端都会传给服务端,其他参数则是根据不同接口传不同参数。若以表单的形式提交的数据:

其中请求参数params就是上文所说的其他参数,而除了它都是基本参数,param的值是json字符串,对于这种请求方式用@RequestParam、@RequestBody都不能满足要求,用spring中自定义的参数解析器恰好可以解决这个问题。

首先定义映射参数的类

UserParam:

public class UserParam extends BaseParam{
    private UserInfoEntity params;//其他参数映射类

    public UserInfoEntity getParams() {
        return params;
    }

    public void setParams(UserInfoEntity params) {
        this.params = params;
    }

    public void setParamsFromJson(String json){
        UserInfoEntity userInfoEntity = null;
        try {
            userInfoEntity = JSONUtils.json2pojo(json,UserInfoEntity.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        setParams(userInfoEntity);
    }
}

BaseParam(基础参数类):

public class BaseParam {
    public String token;
    public String channel;
    public String clientId;


    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }
}

Controller类方法

@RestController
public class HelloController {
    @Autowired
    UserInfoService userInfoService;
    @PostMapping(value = "/lios/boot/ok",produces = {"application/json;charset=utf-8"})
    public Object ok(UserParam param){
        return userInfoService.selectByMobile(param.getParams().getMobile());
    }
}

自定义参数解析器类

public class CustomArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Class paramObjClass = methodParameter.getParameterType();
        if(BaseParam.class.isAssignableFrom(paramObjClass)){
            return true; //参数为BaseParam.class类类型时,则执行resolveArgument方法
        }
        return false;
    }
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        Class paramObjClass = parameter.getParameterType();//获取参数类类型

        Object paramObj = paramObjClass.newInstance();//根据class new 出对象

        Map<String, String[]> param = webRequest.getParameterMap();//获取所有请求参数
        for (Map.Entry<String, String[]> entry : param.entrySet()) {
            String[] val = entry.getValue();
            if (val != null && "params".equals(entry.getKey())) {
                Method method = paramObjClass.getMethod("setParamsFromJson", String.class);//获取到方法setParamsFromJson的对象
                method.invoke(paramObj, val[0]);//把params的值当作形参传入
            } else if (val != null && val.length == 1) { //基础类参数处理
                Field field =null;
                if(paramObjClass.getName().equals(BaseParam.class.getName())){
                    field=paramObjClass.getDeclaredField(entry.getKey());
                }else {
                    field= paramObjClass.getSuperclass().getDeclaredField(entry.getKey());
                }
                //把基础参数的值放入UserParam中
                if (field.getType().isAssignableFrom(String.class)) {
                    field.set(paramObj, val[0]);
                } else if (field.getType().isAssignableFrom(Integer.class)) {
                    field.set(paramObj, Integer.valueOf(val[0]));
                } else if (field.getType().isAssignableFrom(Long.class)) {
                    field.set(paramObj, Long.valueOf(val[0]));
                } 
            }
        }
        return paramObj;
    }
}

配置

  • 一般项目配置
<mvc:annotation-driven>
                <mvc:argument-resolvers>
                    <bean class="com.lios.api.resolver.CustomArgumentResolver"/>
                </mvc:argument-resolvers>
            </mvc:annotation-driven>
  • springboot项目中配置
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
        @ImportResource({"classpath*:dispatcher-servlet.xml"})
        public class LiosBootApplication extends WebMvcConfigurerAdapter {
            public static void main(String[] args) {
                SpringApplication.run(LiosBootApplication.class, args);
            }
            @Override
            public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
                super.addArgumentResolvers(argumentResolvers);
                argumentResolvers.add(new CustomArgumentResolver());
            }
        }

本文分享自微信公众号 - 后端沉思录(LiosWangs),作者:LiosWong

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-04-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • mybatis拦截器分表

    mybatis提供了拦截器插件用来处理被拦截的方法的某些逻辑.下面会通过创建8张表,当用户注册时,根据对手机号取余入不同的表.

    LiosWong
  • python小白爬取某东bra数据分析

    最近用python爬取了某东上的x款bra的用户评论,然后进行了size、color分析,直接上图:

    LiosWong
  • 动态代理(一)

    代理模式是Java的一种设计模式,开发中可能会有一种场景,某个类的方法需要补充,但是由于不想在原有的类基础上改动,该如何做呢,如下:

    LiosWong
  • SpringMVC 中的Annotated Controllers

    上面透漏一下信息:是一个GET响应 查找web下的index模版,通过model将数据传递给模版引擎渲染

    大话swift
  • Java-内部类

    如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象(在静态方法内部创建某个内部类的对象),那么必须像在main()方法中那样,具体地指明这个对象的类型...

    桑鱼
  • [享学Eureka] 九、远程通信模块:使用TransportClientFactory构建底层请求客户端完成服务注册、服务下线

    代码下载地址:https://github.com/f641385712/netflix-learning

    YourBatman
  • 【java开发系列】—— 嵌套类与内部类

    嵌套类与内部类在java中使用的很广泛,为了避免难以理解,这里用了几个小例子,说明它的用法。   嵌套类与内部类的结构如下图 ?   静态嵌套类     ...

    用户1154259
  • 九、委派模式与模板模式详解

    委派模式(Delegate Pattern ) 又叫委托模式, 是一种面向对象的设计模式, 允许对象组合实现与 继承相同的代码重用。它的基本作用就是负责任务的...

    编程之心
  • Java描述设计模式(02):简单工厂模式

    1)、OCP原则:软件实体,如类、模块和函数,应当对扩展开放,但对修改关闭。 2)、违反设计模式的OCP原则,新增食品类不方便扩展,代码改动较大。

    知了一笑
  • Java编程思想第五版(On Java8)(十一)-内部类

    内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可见性。然而必须要了解,内部类与组合是完全不同的概念,这一点很重要。在...

    JavaEdge

扫码关注云+社区

领取腾讯云代金券