之前想的比较简单,请求到达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类就是上面这样。

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

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

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

    当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...

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

    当交易由Action进入Service之前,需要根据不同的Service实际负责业务的不同,真正执行Service的业务逻辑之前,做一些检查工作.这样的拦截器应该是基于配置的,与Service关联起来 ...

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

    [工程截图] [PersonDao.java] package com.HigginCui.dao; public interface PersonDao { public void savePers ...

  4. Action调用Service

    Java Web项目,写到Action的时候,往往会要引入Service,这个是一个常见的操作. 但是,我自认为引入Service需要给它get和set方法,并且这个习惯已经沿用到现在.然而,自从参与 ...

  5. SpringBank 开发日志 使用maven构建dubbo服务的可执行jar包

    写这篇日志的时候,我已经完成了这个目标,并且中间经历了一次面试.现在回过头看,已经觉得印象不那么深刻了,果然还是一边思考,一边记录这样最好.但我还是严格要求自己,从新做了梳理,对相关配置进行了整理和说 ...

  6. springbank 开发日志 springbank是如何注册handler的

    这要从DefaultAnnotationHandlerMapping这个类说起,该类被@Component注释,该类被Spring IOC容器实例化之后,将会执行其initApplicationCon ...

  7. springbank 开发日志 Spring启动过程中对自定义标签的处理

    这篇随笔的许多知识来源于:http://www.importnew.com/19391.html 之所以会去看这些东东,主要是希望能够模仿spring mvc的处理流程,做出一套合理的交易处理流程. ...

  8. 12_注解04_注解实现Action调用Service,Service调用Dao的过程

    [工程截图] [PersonDao.java] package com.HigginCui.annotation; public interface PersonDao { public void s ...

  9. SpringBank 开发日志 Mybatis 使用redis 作为二级缓存时,无法通过cacheEnabled=false 将其关闭

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...

随机推荐

  1. Java编程思想 学习笔记8

    八.多态  在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征. 多态通过分离做什么和怎么做,从另一角度将接口和实现分离开来. “封装”通过合并特征和行为来创建新的数据类型.“实现 ...

  2. Git基础考试题

    Git: 1.在windows上搭建git环境,成功后查看版本号 Linux安装 sudo apt-get install git -y yum install git -y windows直接安装e ...

  3. Keil stm32 printf到Debug窗口

    使用JlinkV8+Keil41.在main.c输入以下代码 #include <stdio.h> #define ITM_Port8(n) (*((volatile unsigned c ...

  4. C# Winform继承窗体打开设计器白屏的一例解决方法

    环境VS2017 15.5.4,Win10开发过程中,发现一些窗体打开设计器会卡死白屏,另外有一些不会,(两者运行时正常),最小化vs后甚至能把工具箱连带搞黑,严重影响开发效率,经过一天多的对比研究, ...

  5. HttpWebRequest post 提交 C#的WebBrowser操作frame如此简单 WebClient 提交

    //http://www.cnblogs.com/cgli/archive/2011/04/09/2010497.html System.Net.ServicePointManager.Expect1 ...

  6. CF949D Curfew

    传送门 跟这个大佬学的->戳我 假设只有一个宿管,那么从前往后做的过程中,如果能到达某个寝室范围内的人数不够\(b\),那么不如把这个寝室空出来,这样更有利于后面的抉择;反之,就把这个寝室搞正好 ...

  7. mysql 案例~ mysql故障恢复

    一 :遇到一个朋友的案例 分享下处理流程 二 : 现象 1 mysql无法启动,观察日志发现 InnoDB: Failing assertion: !m_fatal InnoDB: We intent ...

  8. mysql 开源~canal的深度解读1

    一 简介:经过一段时间的研究,对canal有了一些见解 二 配置文件: 1 canal.properties (系统根配置文件)     主要参数列表   canal.properties (系统根配 ...

  9. typedef 用法总结

    原文转自:http://www.cnblogs.com/ggjucheng/archive/2011/12/27/2303238.html 引言 typedef 声明,简称 typedef,为现有类型 ...

  10. SpringBoot定制错误的Json数据

    (1)自定义异常处理&返回定制Json数据 @ControllerAdvice public class MyExceptionHandler { @ResponseBody @Excepti ...