`

HandlerMethodArgumentResolver 自定义封装参数bean

阅读更多

       小生最近写代码遇到一个小问题,一个controller有8个api,不过有7个api依赖登录api记录的session。如果session存在,则需要从session中获取clientId和password,否则退出到登录页面。

        最开始我是在BaseController 中定义了一个公用的设置clientId和password的方法,后来发现这样很不优雅。于是想到了拦截器,但是拦截器针对每个方法都会调用,而且定位待处理的参数也不方便。最后我想到

HandlerMethodArgumentResolver 加注解的方式。下面贴出代码片段。

         
        

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface BrokerRequestArgument {
}

    

public class BrokerRequestResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterAnnotation(BrokerRequestArgument.class) != null;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String token = webRequest.getHeader("X-token");
        LoginUserModel loginUserModel = (LoginUserModel) webRequest.getAttribute(token, RequestAttributes.SCOPE_SESSION);

        Object obj = BeanUtils.instantiate(parameter.getParameterType());
        BeanWrapper wrapper = PropertyAccessorFactory
                .forBeanPropertyAccess(obj);
        Field[] fields = parameter.getParameterType().getDeclaredFields();
        Map<String, Field> fieldMap = Maps.newHashMap();
        for (Field field : fields) {
            fieldMap.put(field.getName(), field);
        }

        for (Iterator<String> paramNames = webRequest.getParameterNames(); paramNames.hasNext(); ) {
            String paramName = paramNames.next();
            Object o = webRequest.getParameter(paramName) ;
            wrapper.setPropertyValue(paramName,o);
        }
        wrapper.setPropertyValue("clientId",loginUserModel.getClientId());
        wrapper.setPropertyValue("password",loginUserModel.getPassword());
        return obj;
    }
}

 

    

<mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="
cn.xxx.xxx.web.resolver.BrokerRequestResolver" lazy-init="false"/>
        </mvc:argument-resolvers>
 </mvc:annotation-driven>

 

    

@RequestMapping(value = "/his_trade_entrusts", method = RequestMethod.GET)
    @ResponseBody
    public String hisEntrustQry(HttpServletRequest request, PagingQueryRequest brokerRequest) {
        setClientIdAndPassword(request,brokerRequest);
        BrokerResponse brokerResponse = guojinTradeService.hisEntrustQry(brokerRequest);
        return pagingResponse(brokerResponse);
    }

//变成了

@RequestMapping(value = "/his_trade_entrusts", method = RequestMethod.GET)
    @ResponseBody
    public String hisEntrustQry( @BrokerRequestArgument PagingQueryRequest brokerRequest) {
        BrokerResponse brokerResponse = guojinTradeService.hisEntrustQry(brokerRequest);
        return pagingResponse(brokerResponse);
    }

   
    这样代码就优雅多了!

分享到:
评论

相关推荐

    allegro自定义封装.

    ### Allegro自定义封装制作详解 #### 一、概述 Allegro是一款广泛应用于电子设计自动化领域的软件,尤其在印刷电路板(PCB)设计方面表现突出。自定义封装是Allegro的一项重要功能,它允许用户根据实际需求创建...

    ActionSheet_自定义封装

    6. **示例代码**:提供的“ActionSheet_自定义封装”可能包含一个简单的使用示例,展示了如何创建一个ActionSheet实例,设置参数并展示出来。这对于初学者来说是非常有帮助的,他们可以直接运行这个示例,理解封装后...

    基于鸿洋okhttputils 封装数据 bean和callback 回调

    本主题主要探讨的是如何基于鸿洋的OkHttpUtils进行数据Bean的封装以及Callback回调的处理。 首先,我们来理解一下OkHttpUtils的核心概念。OkHttpUtils提供了一系列静态方法,如`get()`, `post()`等,用于发起HTTP...

    常用的自定义的封装

    而"常用的自定义的封装"这个主题,指的是设计者根据实际需求创建或修改的PCB元件封装模型。封装是PCB设计中的一个重要组成部分,它代表了实际电路板上元器件的物理形状和电气连接方式。 Altium Designer是一款强大...

    C++自定义封装socket操作业务类完整实例

    本实例提供了在Linux环境下实现C++自定义封装socket操作业务类的详细过程,允许开发者轻松地创建socket连接、设置参数以及发送请求。 首先,`SocketConnector` 类是核心业务类,它包含了与socket相关的各种操作。类...

    OC-高度自定义封装tabbar框架

    本文将详细解析"OC-高度自定义封装tabbar框架"这一主题,探讨如何通过Objective-C(OC)对原生TabBar进行自定义封装,以实现更高的灵活性和扩展性,同时保持系统的稳定性和兼容性。 首先,我们要明白原生TabBar的...

    自定义封装分享页面弹框

    在iOS开发中,自定义封装分享页面是一种常见的需求,它能提供更加个性化和符合应用风格的分享体验。本文将深入探讨如何使用Xib(界面构建器)来封装一个自定义的分享页面弹框。 首先,我们需要理解Xib的作用。Xib...

    swift-自定义封装轮播图

    "swift-自定义封装轮播图"项目就是这样一个例子,它提供了一种高效、灵活的方式来展示图片轮播效果。在这个项目中,开发者创建了一个自定义的轮播图控件,可以满足无限轮播和普通轮播的需求,同时还有自定义的...

    蓝牙自定义封装

    "蓝牙自定义封装"是一种为了简化开发者工作,提高效率的方法。通过自定义封装,开发者可以避免直接处理蓝牙低能耗(BLE,Bluetooth Low Energy)的复杂性,比如苹果提供的Core Bluetooth框架中涉及的大量协议和操作...

    swift-自定义封装UITableView和MJRefresh相结合

    本文将深入探讨如何在Swift中自定义封装`UITableView`与`MJRefresh`,以创建一个高效、灵活且易于维护的列表视图。 首先,我们从`UITableView`的自定义封装开始。自定义封装`UITableView`的主要目标是将复杂的表格...

    基于c#自定义封装控件(IP地址填写控件)

    为了提高用户体验和界面的一致性,开发者会自定义封装控件。在这个场景下,"基于C#自定义封装控件(IP地址填写控件)"的实践是为了创建一个专门用于输入IP地址的用户界面元素。 自定义控件是.NET框架中的一个重要...

    WPF之自定义窗体的封装

    本文将深入探讨如何在WPF中封装自定义窗体,以及这一过程涉及的关键知识点。 首先,我们要理解WPF的基本架构。WPF是.NET Framework的一部分,它提供了丰富的UI框架,包括XAML(eXtensible Application Markup ...

    Protel 99 自定义封装教程

    Protel 99se学习自定义PCB的封装

    Unity自定义封装Debug类

    自定义调试类,更加便捷的使发布后的程序,直接在主界面观看所自行输出的Log;右下角可一键清理输出内容,也可一键 开启/关闭 log滚动查看。开启可通过修改 常量:isOpenTheDebug = ture ,轻松便捷。解决了以往自行...

    跟学STM32江科大教程,自定义封装库

    跟学STM32江科大教程,自定义封装库

    案例实战-SpringBoot3.x自定义封装starter实战

    在本案例实战中,我们将深入探讨如何在Spring Boot 3.x框架中自定义并封装一个starter。Spring Boot的starter是其核心特性之一,它提供了一种便捷的方式来配置和使用各种功能模块,使得开发者可以快速搭建应用。理解...

    微信小程序 - 自定义picker 封装成插件

    微信小程序 - 自定义picker 封装成插件 可以自定义多级数据picker 最多四级 最少一级 自定义二级数据联动 自定义三级数据联动 自定义四级数据联动 封装成插件 全局使用

    C#绘制曲线自定义封装

    本篇文章将详细讲解如何利用C#实现曲线的自定义封装,包括封装绘制曲线的类、数据输入处理以及图形界面的交互。 首先,我们需要创建一个专门用于绘制曲线的类。这个类通常包含以下几个核心组件: 1. **绘图面板**...

    ksoap2调用webService服务 包含自定义参数 自定义参数集合等

    - 自定义类型参数:需要创建一个与服务端对应的Java类,并使用SoapObject封装这个类的实例。然后,将这个SoapObject作为参数添加到请求中。 - 带有自定义类型属性的自定义类型参数:需要对每个属性进行类似处理,...

    自定义封装Qt柱状图类,实现数据动态更新和鼠标数值显示

    在本文中,我们将深入探讨如何使用Qt库来创建一个自定义封装的柱状图类,以便实现数据的动态更新和鼠标悬停时显示数值的功能。Qt是一个强大的跨平台应用程序开发框架,提供了丰富的图形用户界面(GUI)组件,包括...

Global site tag (gtag.js) - Google Analytics