之前想的比较简单,请求到达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类就是上面这样。
这样一来就避免立刻了在代码中出现强制转换的多余的代码,当然编译器可能也是强转的。但至少自己写的代码看起来整洁多了