SpringBank 开发日志 重新设计Action调用Service的参数传递 使用泛型解决类型转换问题

之前想的比较简单,请求到达controller的时候,传给action的参数没有经过任何封装,就是一个Map。然后action再调用service的时候,传递的参数也是map

@Controller
public class DepositController extends BaseController{
    @TransactionMapping(transaction = "Deposit")
    public Map Deposit(Map request) {
        Map map = callService(ServiceDict.DepositService, request);
        return map;
    }
}

但是当我在做存款交易的时候,我隐隐约感觉这样很有问题,因为再action里面完全无法看出来付款人收款人金额等等重要信息,虽然实际上这些信息在调用Service之前会经过一系列拦截器,但是当到达service里面的时候,参数又要从map里面get一遍,感觉很不舒服,就像没有经过校验的原始数据一样。

所以我想确实action调用service的时候,应该将参数封装到专门的请求参数类里面。

// 日切
    @TransactionMapping(transaction = "NextAccountingDate")
    public Map nextAccountingDate(Map request) {
        Map map = callService(ServiceDict.NextAccountingDateService,new NextAccountingDateRequest());
        return map;
    }

以日切交易为例,我搞了一个NextAccountingDateRequest,封装该Service需要的参数(实际上这个交易没有任何参数,只是举例)

public abstract class Service {

    private List<Interceptor> interceptorList;

    @SuppressWarnings("rawtypes")
    public abstract Map execute(Object request);

    public List<Interceptor> getInterceptorList() {
        return interceptorList;
    }
    public void setInterceptorList(List<Interceptor> interceptorList) {
        this.interceptorList = interceptorList;
    }
}

但是我是反射的方式调用Service,所有的service都继承了上面的这个抽象类Service,所以execute方法的参数就是需要考虑的问题。一开始如上图所示,我使用Object来接收,可是Service里面呢

public class NextAccountingDateService extends Service<NextAccountingDateRequest>{

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Map execute(NextAccountingDateRequest request) {
        // TODO Auto-generated method stub
        Map result = new HashMap();

        //先查出当前账务日期
        String pdat = DaoUtil.getMapper(SysparamMapper.class).selectByPrimaryKey(CommonDict.PDAT).getValue();
        Date currentDate = DateUtil.getDateFromStr(pdat);

        //计算下一日期
        Date nextDate = DateUtil.getNextDate(currentDate);

        //record
        Sysparam record = new Sysparam();
        record.setValue(DateUtil.getDateDashFormat(nextDate));

        //example
        SysparamExample example = new SysparamExample();
        example.createCriteria().andKeyEqualTo(CommonDict.PDAT);

        //do update
        DaoUtil.getMapper(SysparamMapper.class).updateByExampleSelective(record, example);

        //query again
        pdat = DaoUtil.getMapper(SysparamMapper.class).selectByPrimaryKey(CommonDict.PDAT).getValue();

        result.put("pdat", pdat);
        return result;
    }
}

这里肯定就编译不过了,需要强转。所以为了解决这个问题,最终使用了泛型

public abstract class Service<T> {

    private List<Interceptor> interceptorList;

    @SuppressWarnings("rawtypes")
    public abstract Map execute(T request);

    public List<Interceptor> getInterceptorList() {
        return interceptorList;
    }
    public void setInterceptorList(List<Interceptor> interceptorList) {
        this.interceptorList = interceptorList;
    }
}

使用泛型过后的抽象Service类就是上面这样。

这样一来就避免立刻了在代码中出现强制转换的多余的代码,当然编译器可能也是强转的。但至少自己写的代码看起来整洁多了

时间: 2024-10-27 05:59:04

SpringBank 开发日志 重新设计Action调用Service的参数传递 使用泛型解决类型转换问题的相关文章

Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)

当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.lang.NullPointerException) 按上述步骤解决完自己的工具类后,你会发现项目运行后仍然报空指针此时你需要在applicationContext.xml 配置文件中添加一行配置文件 如图: 对自己工具类所在的包进行注解扫描,使Spring能够识别自己上面所配置的注解 原文地址:htt

SpringBank 开发日志 一种简单的拦截器设计实现

当交易由Action进入Service之前,需要根据不同的Service实际负责业务的不同,真正执行Service的业务逻辑之前,做一些检查工作.这样的拦截器应该是基于配置的,与Service关联起来的. /** * @author wangxin * @contact [email protected] * @date Jul 22, 2017 * @Description: 所有TransactionController的抽象父类,主要作用为以一种低耦合的方式调用Service */ pub

08_Spring实现action调用service,service调用dao的过程

[工程截图] [PersonDao.java] package com.HigginCui.dao; public interface PersonDao { public void savePerson(); } [PersonDaoImpl.java] package com.HigginCui.dao; public class PersonDaoImpl implements PersonDao{ @Override public void savePerson() { System.o

springbank 开发日志 阅读spring mvc的源代码真是受益良多

决定模仿spring mvc的dispatcher->handlerMapping(return executorChain)->handler.execute 这样的流程之后,就开始看spring mvc的源代码. 因为我也自定义了标签,来做交易名映射,根据交易名找到处理类.所以我着重需要看的,就是spring mvc是如何根据url找到对应的handler的. 既然要找,首先要有个找的地方,spring mvc是这样做的,它搞了AbstractDetectingUrlHandlerMapp

springbank 开发日志 springbank是如何执行一个handler的requestMapping对应的方法的

占位 从dispatcher说起,方法doDispatch(Map request)的参数request是一个通过解析来报报文新城的map 要以request为参数执行一个handler,自然要先找到这个handler,这个工作是由getHandler(request)完成,其实找到的是handlerExecutionChain,是一个包含了拦截器链和真正的handler在内的执行链, 方法内的步骤建立在handlerMappings的基础上,

第四章 Android开发三大基石—Activity、Service和Handler(4)

4.2千变万化的服务-Service开发 Service是Android系统中运行在后台.不和用户交互应用组件.它和Activity的级别差不多,只能在后台运行.每个Service必须在manifest文件中 通过<service>来声明. 4.2.1 Service的生命周期 Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service的时候,先后调用onCreate().onSta

常规功能和模块自定义系统 (cfcmms)—030开发日志(创建ManyToMany的column5)

030开发日志(创建ManyToMany的column5) 现在对于这个字段来说,还剩最后一个功能了,那就是可以修改ManyToMany的值了.在grid的inline操作里面,是可以直接删除已有值,但是如果要新增的话,就必须要有一个新的界面了.下面来看看开发修改ManyToMany字段所需要的步骤. 1.创建一个修改窗口,在里面创建一个可check的树: 2?到后台请求数据,读取当前记录的所有的ManyToMany的可选项,并把已经选中的打勾: 3?根据读取到的数据更新树: 4?用户操作che

Android学习笔记二十六.跨进程调用Service(AIDL Service)

跨进程调用Service(AIDL Service) 一.AIDL Service 1.什么是AIDL Service? AIDL,即Android Interface Definition Language.是Android用于定义远程接口,AIDL接口定义语言的语法比较简单,这种接口定义语言并不是真正的编程语言,它只是定义两个进程之间的通信接口.AIDL的语法与Java接口很相似,但存在如下几点差异: (1)AIDL定义接口的源代码必须以.aidl结尾; (2)AIDL接口中用到数据类型,除

.NET Core开发日志——RequestDelegate

本文主要是对.NET Core开发日志--Middleware的补遗,但是会从看起来平平无奇的RequestDelegate开始叙述,所以以其作为标题,也是合情合理. RequestDelegate是一种委托类型,其全貌为public delegate Task RequestDelegate(HttpContext context),MSDN上对它的解释,"A function that can process an HTTP request."--处理HTTP请求的函数.唯一参数,