微服务的一些良好规范及实践代码记录

MsgResult


@Data
@SuppressWarnings("unchecked")
public class MsgResult<T> {

    /**
     * code 错误码
     */
    private String code;

    /**
     * msg 错误信息
     */
    private String msg;

    /**
     * data 返回的数据
     */
    private T result;


    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public T getResult() {
        return result;
    }

    public void setResult(T result) {
        this.result = result;
    }

    public MsgResult(String code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.result = data;
    }

    public MsgResult(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public MsgResult() {
    }

    public  MsgResult fail(ServerEnum serverEnum){
        this.code =serverEnum.getCodePrefix() + ResultCodeEnum.ERROR.getCode();
        this.msg = ResultCodeEnum.ERROR.getDesc();
        this.result=null;
        return this;
    }

    public MsgResult success(T t){
        this.code = ResultCodeEnum.SUCCESS.getCode();
        this.msg = ResultCodeEnum.SUCCESS.getDesc();
        this.result=t;
        return this;
    }

    public boolean isSuccess(){
        return ResultCodeEnum.SUCCESS.getCode().equals(this.code);
    }

    public static MsgResult successStatic(Object data){
        MsgResult result = new MsgResult();
        result.code = ResultCodeEnum.SUCCESS.getCode();
        result.msg = ResultCodeEnum.SUCCESS.getDesc();
        result.result=data;
        return result;
    }


    public static MsgResult failStatic(ServerEnum serverEnum){
        MsgResult result = new MsgResult();
        result.code =serverEnum.getCodePrefix() + ResultCodeEnum.ERROR.getCode();
        result.msg = ResultCodeEnum.ERROR.getDesc();
        result.result=null;
        return result;
    }

}


comomon  aop 日志切面


/**日志切面aop
*/
@Component
@Aspect
public class ControllerParamsAspect {

    private static Logger logger = LoggerFactory.getLogger(ControllerParamsAspect.class);

    private static ThreadLocal<Long> startTime = new ThreadLocal<>();

/*    @Pointcut("execution(public com.pld.common.util.MsgResult *..controller..*(..)) " +
            "|| execution(public com.pld.common.util.MsgResult *..connector..*(..))")*/

    /**
     * 如果一个方法内部调用其它方法,如果被调用的方法也满足controllerLog规则,那么在同一个线程里面就会触发多次doBefore和doAfterReturning
     * 这时会引起一个问题,只有在最后一个满足的方法里面能正确得到startTime.get()的值,后续的方法都会报空指针错误。因为最后一个方法的doAfterReturning已经执行了startTime.remove(),
     * 它们又是在同一个线程里面。
     */
    @Pointcut("controllerLog() && !remoteLog()")
    public void webLog() {
        logger.info("webLog");
    }

    /**
     * 服务内部通过fegin的方式
     */
    @Pointcut("execution(public com.pld.common.util.MsgResult *..remote..*(..)) ")
    public void remoteLog(){
        logger.info("remote log");
    };

    /**
     * controller方法
     */
    @Pointcut("execution(public com.pld.common.util.MsgResult *..controller..*(..)) ")
    public void controllerLog(){
        logger.info("controller log");
    };


    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        startTime.set(System.currentTimeMillis());
        // 记录http请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            logger.warn("获取不到上下文信息");
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        // 打印请求内容
        logger.info("===============请求内容start===============");
        logger.info("请求地址: {}", request.getRequestURL());
        logger.info("请求方式: {}", request.getMethod());
        logger.info("请求系统标识entCode:{}",request.getHeader("entCode"));
        logger.info("请求类方法: {}", joinPoint.getSignature());
        logger.info("请求类方法参数: {}",  joinPoint.getArgs());
        logger.info("===============请求内容end===============");

    }

    @AfterReturning(pointcut="webLog()", returning="returnObj" )
    public void doAfterReturning(JoinPoint joinPoint, Object returnObj) {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(attributes == null){
            logger.warn("获取不到上下文信息");
            return;
        }

        try{
            logger.info("--------------返回内容start----------------");
            HttpServletRequest request = attributes.getRequest();
            logger.info("请求地址:{}",request.getRequestURL());
            logger.info("请求类方法参数: {}", joinPoint.getArgs());
            logger.info("返回参数: {}", JSON.toJSONString(returnObj, SerializerFeature.NotWriteDefaultValue));
            logger.info("请求处理时间为:" + (System.currentTimeMillis() - startTime.get()));
            logger.info("===============返回内容end===============");
            startTime.remove();
        }catch (Exception e){
            logger.warn("doAfterReturning error ",e);
        }

    }
}



/**
 * 2.日记切面 添加MDC 内容
**/
@Component
public class LogInterceptor implements HandlerInterceptor {

    @Value("${spring.application.name}")
    private String serverName;
    /**
     * 会话Id
     */
    public final static String SESSION_ID = "sessionId";
    /**
     * 服务名称
     */
    public final static String SERVER_NAME="serverName";
    private static final Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String xForwardedForHeader = httpServletRequest.getHeader("X-Forwarded-For");

        String sessionId=httpServletRequest.getHeader(LogInterceptor.SESSION_ID);
        if (null != sessionId){
            MDC.put(SESSION_ID, sessionId);
            LOGGER.info("put requestId ({}) to logger", sessionId);
        }else{
            String localSession = MDC.get(SESSION_ID);
            if(null  == localSession || localSession.isEmpty()){
                sessionId = UUID.randomUUID().toString();
            }else{
                sessionId = localSession;
            }

        }
        MDC.put(SESSION_ID, sessionId);
        String serverNameHeader=httpServletRequest.getHeader(LogInterceptor.SERVER_NAME);
        LOGGER.info("HeaderServerName ==" + serverNameHeader);
        if(null != serverNameHeader){
            MDC.put(SERVER_NAME, serverNameHeader);
        }else {
            LOGGER.info("serverName ==" + serverName);
            MDC.put(SERVER_NAME, serverName);
        }
        String remoteIp = httpServletRequest.getRemoteAddr();

        LOGGER.info("session id:{}, client ip:{}, X-Forwarded-For:{},url :{}", sessionId, remoteIp, xForwardedForHeader,httpServletRequest.getRequestURI());

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView)  {
      }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e)  {
        String uuid = MDC.get(SESSION_ID);
        LOGGER.info("remove requestId ({}) from logger", uuid);
        MDC.remove(SESSION_ID);

    }
}
/**
**2.TypeFilter 排除common包切面,视项目具体情况使用
*/
@Slf4j
public class ExcludeControllerAspectFilter implements TypeFilter {

    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        log.info("className:{}", classMetadata.getClassName());
        if(classMetadata.getClassName().contains("ControllerParamsAspect")) {
            return true;
        }
        return false;
    }
}


统一异常处理controller advice

GlobalExceptionHandle

/**
 * 统一异常处理
 * @author tlj
 * @date 2019/6/3
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandle {


    /**
     * 全局异常捕捉处理
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public MsgResult errorHandler(Exception ex) {
        log.warn("系统错误:{}", ex);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(ProductResultCodeEnum.PRODUCT_CENTER_EXCEPTION.getCode());
        msgResult.setMsg(ProductResultCodeEnum.PRODUCT_CENTER_EXCEPTION.getMsg());
        return msgResult;
    }
    /**
     * 全局异常捕捉处理
     */
    @ResponseBody
    @ExceptionHandler(value = IllegalArgumentException.class)
    public MsgResult errorHandler(IllegalArgumentException ex) {
        log.warn("IllegalArgumentException:{}", ex);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(ProductResultCodeEnum.PRODUCT_PARAM_ERROR.getCode());
        msgResult.setMsg(ProductResultCodeEnum.PRODUCT_PARAM_ERROR.getMsg());
        return msgResult;
    }
    /**
     * 不支持该请求方式
     */
    @ResponseBody
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public MsgResult errorHandler(HttpRequestMethodNotSupportedException ex) {
        log.warn("系统错误:{}", ex);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(ProductResultCodeEnum.REQUEST_METHOD_NOT_SUPPORT.getCode());
        msgResult.setMsg(ProductResultCodeEnum.REQUEST_METHOD_NOT_SUPPORT.getMsg());
        return msgResult;
    }
    /**
     * 参数异常
     */
    @ResponseBody
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public MsgResult errorHandler(HttpMessageNotReadableException ex) {
        log.warn("参数异常:{}", ex);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(ProductResultCodeEnum.PRODUCT_PARAM_ERROR.getCode());
        msgResult.setMsg(ProductResultCodeEnum.PRODUCT_PARAM_ERROR.getMsg());
        return msgResult;
    }

    /**
     * 三湘银行 异常
     */
    @ResponseBody
    @ExceptionHandler(value = SXPaymentApiException.class)
    public MsgResult sxErrorHandler(SXPaymentApiException pldException) {
        log.error("SXPaymentApiException警告:{}", pldException);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(pldException.getCode());
        msgResult.setMsg(pldException.getMsg());
        return msgResult;
    }

    /**
     * 打印到日志为error级别的 异常
     */
    @ResponseBody
    @ExceptionHandler(value = PldErrorException.class)
    public MsgResult sxErrorHandler(PldErrorException pldException) {
        ProductResultCodeEnum resultCode = pldException.getResultCode();
        log.error("PldErrorException异常:{}", pldException);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(resultCode.getCode());
        msgResult.setMsg(resultCode.getMsg());
        if( pldException.getData()!=null ){
            msgResult.setResult(pldException.getData());
        }
        return msgResult;
    }
    /**
     * 捕获程序显式抛出的异常
     */
    @ResponseBody
    @ExceptionHandler(value = PldException.class)
    public MsgResult pldMessageErrorHandler(PldException pldException) {
        ProductResultCodeEnum resultCode = pldException.getResultCode();
        log.warn("PldException警告:{}", pldException);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(resultCode.getCode());
        msgResult.setMsg(resultCode.getMsg());
        if( pldException.getData()!=null ){
            msgResult.setResult(pldException.getData());
        }
        return msgResult;
    }
    /**
     * 捕获程序显式抛出的异常(带附加信息)
     */
    @ResponseBody
    @ExceptionHandler(value = PldDetailException.class)
    public MsgResult pldMessageErrorHandler(PldDetailException pldContentException) {
        ProductResultCodeEnum resultCode = pldContentException.getResultCode();
        log.warn("PldDetailException警告:{}", pldContentException);
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(resultCode.getCode());
        String msgExtra = pldContentException.getExtraMsg();
        msgResult.setMsg(resultCode.getMsg()+(StringUtils.isEmpty(msgExtra)?"":(":"+msgExtra)));
        return msgResult;
    }

    /**
     * 拦截参数异常
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public MsgResult validErrorHandler(MethodArgumentNotValidException ex) {
        log.warn("参数校验错误:{}", ex);
        BindingResult bindingResult = ex.getBindingResult();
        StringBuilder sb = new StringBuilder();
        if (bindingResult.hasErrors()) {
            for (ObjectError error : bindingResult.getAllErrors()) {
                sb.append(error.getDefaultMessage()).append(";");
            }
        }
        MsgResult msgResult = new MsgResult();
        msgResult.setCode(ProductResultCodeEnum.PRODUCT_NEED_PARAM_EXCEPTION.getCode());
        msgResult.setMsg(ProductResultCodeEnum.PRODUCT_NEED_PARAM_EXCEPTION.getMsg() + sb.toString());
        return msgResult;

    }
}



public enum ProductResultCodeEnum {
    SUCC("200", "成功"),
    PRODUCT_CENTER_EXCEPTION("26000000", "产品中心服务异常 "),
    PRODUCT_NEED_PARAM_EXCEPTION("26000001", "产品中心服务参数错误 "),
    PRODUCT_PARAM_ERROR("26000002", "提交的参数有误."),
    REQUEST_METHOD_NOT_SUPPORT("26000003", "不支持该请求方式"),
    OUTER_SERVICE_ERROR("26000004", "外部服务请求异常"),
    ENCRYPT_DECRYPT_ERROR("26000005", "加解密异常"),
    SIGN_ERROR("26000006", "签名异常"),
    OSS_TOKEN_ERR("26000007", "OSS token获取失败"),
    ATTACHMENT_NOT_EXIST("26000008", "附件或图片不存在"),
    ATTACHMENT_URL_OBJECT_KEY_NULL("26000009", "附件或图片的url和objectKey不能同时为空"),

    DATA_RECORD_NOT_EXIST("26100000", "数据记录不存在"),
    SEQUENCE_ERROR("26100001", "序列生成异常"),
    SEQUENCE_SIZE_REACH_MAX("26100002", "序列长度已达到设置的最大值"),

    CATEGORY_NAME_EXIST("26200001", "分类名称不可重复"),
    CATEGORY_CODE_EXIST("26200002", "分类代码不可重复"),
    
    ;

    private String code;

    private String msg;

    ProductResultCodeEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

}

@EqualsAndHashCode(callSuper = true)
@Getter
@Slf4j
public class PldDetailException extends RuntimeException implements Serializable {

    private static final long serialVersionUID = -5980209755107175431L;

    /**
     * code 错误码
     */
    final ProductResultCodeEnum resultCode;
    final String extraMsg;

    public PldDetailException(ProductResultCodeEnum resultCode, String extraMsg) {
        super(resultCode.getMsg());
        this.resultCode = resultCode;
        this.extraMsg=extraMsg;
    }

}


junit test


/**
 * @author tlj
 * @date 2019/5/27
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = PldProductCenterApplication.class)
@AutoConfigureMockMvc
@WebAppConfiguration
public abstract class BaseApplicationTest {
    protected MockMvc mvc;
    @Autowired
    private WebApplicationContext context;

    @PersistenceContext
    protected EntityManager entityManager;

    @Before
    public void setupMockMvc()  {
        mvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    /**
     * 基本断言
     * @param action
     * @return
     * @throws Exception
     */
    protected ResultActions basicExpect(ResultActions action) throws Exception {
        action.andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
        action.andExpect(jsonPath("$.code", Matchers.is(ResultCodeEnum.SUCCESS.getCode())))
                .andExpect(jsonPath("$.msg", Matchers.is(ResultCodeEnum.SUCCESS.getDesc())));
        return action;
    }
}



/**
 * @author tlj
 * @date 2019/10/22
 */
@Slf4j
@Transactional
public class BackendCategoryControllerTest extends BaseApplicationTest{
    private static final String TESTID1 ="testId1";
    private static final String USERID2 ="userId2";
    @Before
    public void dataReady(){
        // 前置数据
        String insetSql ="INSERT INTO `pld_product_center`.`t_base_category` (`id`, `create_by`, `date_created`, `date_last_update`, `status`, `update_by`, `version`, `name`, `bus_status`, `code`, `grade`, `parent_id`) VALUES ('testId1', 'userId1', '2019-10-18 10:55:21', '2019-10-18 11:11:52', '1', 'userId2', '3', 'nameTest123', '0', 'codeTest123', '1', '')";
        entityManager.createNativeQuery(insetSql).executeUpdate();
    }
    /**
     *  新增分类
     * @throws Exception
     */
    @Test
    public void categoryAdd() throws Exception {
        CategoryAddDTO req = new CategoryAddDTO();
        req.setCode("codeTest1");
        req.setName("nameTest1");
        req.setUserId("userId1");
        req.setParentId("");
        req.setAuthor("author1");

        String requestJson = JSONObject.toJSONString(req);
        assert StringUtils.isNotBlank(requestJson);
        log.info("新增分类,请求参数{}",requestJson);
        ResultActions action = mvc.perform(MockMvcRequestBuilders.post( Routes.BASE_CATEGORY_ADD )
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(requestJson));
        action.andExpect(MockMvcResultMatchers.status().isOk());
        basicExpect(action).andReturn();
    }
    /**
     *  修改分类
     * @throws Exception
     */
    @Test
    public void categoryEdit() throws Exception {

        CategoryEditDTO req = new CategoryEditDTO();
        req.setId(TESTID1);
        req.setName("nameTest123");
        req.setUserId(USERID2);

        String requestJson = JSONObject.toJSONString(req);
        log.info("修改分类,请求参数{}",requestJson);
        assert StringUtils.isNotBlank(requestJson);
        ResultActions action = mvc.perform(MockMvcRequestBuilders.post( Routes.BASE_CATEGORY_EDIT )
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(requestJson));
        action.andExpect(MockMvcResultMatchers.status().isOk());
        basicExpect(action).andReturn();
    }

    /**
     *  加载同一级分类
     * @throws Exception
     */
    @Test
    public void categoryGradeList() throws Exception {
        CategoryGradeListDTO req = new CategoryGradeListDTO();
        req.setParentId("");

        String requestJson = JSONObject.toJSONString(req);
        log.info("加载同一级分类,请求参数{}",requestJson);
        ResultActions action = mvc.perform(MockMvcRequestBuilders.post( Routes.BASE_CATEGORY_GRADE_LIST )
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(requestJson));
        action.andExpect(MockMvcResultMatchers.status().isOk());
        basicExpect(action).andReturn();
    }
    /**
     *  分类列表搜索
     * @throws Exception
     */
    @Test
    public void categoryPage() throws Exception {
        CategoryPageQueryDTO req = new CategoryPageQueryDTO();
        req.setName("name");
        req.setBusStatus(1);
        req.setCurrentPage(0);
        req.setOrderBy("id");
        req.setPageSize(10);
        req.setXsc("desc");

        String requestJson = JSONObject.toJSONString(req);
        log.info("分类列表搜索,请求参数{}",requestJson);
        ResultActions action = mvc.perform(MockMvcRequestBuilders.post( Routes.BASE_CATEGORY_PAGE )
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(requestJson));
        action.andExpect(MockMvcResultMatchers.status().isOk());
        basicExpect(action).andReturn();
    }
    /**
     *  启用分类
     * @throws Exception
     */
    @Test
    public void categoryOn() throws Exception {
        CategoryOnDTO req = new CategoryOnDTO();
        req.setId(TESTID1);
        req.setUserId(USERID2);

        String requestJson = JSONObject.toJSONString(req);
        log.info("启用分类,请求参数{}",requestJson);
        ResultActions action = mvc.perform(MockMvcRequestBuilders.post( Routes.BASE_CATEGORY_ON)
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(requestJson));
        action.andExpect(MockMvcResultMatchers.status().isOk());
        basicExpect(action).andReturn();
    }

    /**
     *  禁用分类
     * @throws Exception
     */
    @Test
    public void categoryOff() throws Exception {
        CategoryOffDTO req = new CategoryOffDTO();
        req.setId(TESTID1);
        req.setUserId(USERID2);

        String requestJson = JSONObject.toJSONString(req);
        log.info("禁用分类,请求参数{}",requestJson);
        ResultActions action = mvc.perform(MockMvcRequestBuilders.post( Routes.BASE_CATEGORY_OFF)
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(requestJson));
        action.andExpect(MockMvcResultMatchers.status().isOk());
        basicExpect(action).andReturn();
    }

    /**
     *  查询单个分类
     * @throws Exception
     */
    @Test
    public void categoryGet() throws Exception {
        String id = TESTID1;
        log.info("查询单个分类,请求参数id:{}",id);
        ResultActions action = mvc.perform(MockMvcRequestBuilders.get( Routes.BASE_CATEGORY_GET )
                .contentType(MediaType.APPLICATION_JSON_UTF8).param("id",id));
        action.andExpect(MockMvcResultMatchers.status().isOk());
        basicExpect(action).andReturn();
    }


}



/**
 * @author tlj
 * @date 2019/7/30
 */
public class LianLianReconciliationServiceImplTest extends BaseApplicationTest {
    @Autowired
    @MockBean
    private SftpService fileSystemService;
    @Autowired
    @MockBean
    private ReconciliationService reconciliationService;



    /**
     * sftp 对账(日明细)
     * 1.下载sftp文件(test:使用mockbean,替换为本地对账文件)
     * 2.读取对账文件,转换为javabean
     * 3.对账(todo:具体对账待实现)
     * @throws Exception
     */
    @Test
    public void reconciliationDateDetail() throws Exception {
        List<String>  list = fileSystemService.listFiles("/SZ-yuanshi/201906120002511010");
        System.out.println("文件列表:");
        System.out.println(list);
        File file0 = ResourceUtils.getFile("classpath:dateDetailComp.csv");

        Mockito.when(fileSystemService.downloadFile(Mockito.any())).thenReturn(file0);
        File file = fileSystemService.downloadFile("/SZ-yuanshi/201906120002511010/JYMX_201906120002511010_20190716.csv");
        List<ReconciliationDateDetailDTO> dtos = FileUtil.readBuffer(file,ReconciliationDateDetailDTO.class,FileUtil.SPLIT_COMMA);
        dtos.stream().forEach(it-> System.out.println(JSONObject.toJSONString(dtos)));

    }
    /**
     * sftp 对账(月明细)
     * 1.下载sftp文件(test:使用mockbean,替换为本地对账文件)
     * 2.读取对账文件,转换为javabean
     * 3.对账(todo:具体对账待实现)
     * @throws Exception
     */
    @Test
    public void reconciliationMonthDetail() throws Exception {
        List<String>  list = fileSystemService.listFiles("/SZ-yuanshi/201906120002511010");
        System.out.println("文件列表:");
        System.out.println(list);
        File file0 = ResourceUtils.getFile("classpath:monthDetailComp.csv");

        Mockito.when(fileSystemService.downloadFile(Mockito.any())).thenReturn(file0);
        File file = fileSystemService.downloadFile("/SZ-yuanshi/201906120002511010/JYMX_201906120002511010_20190716.csv");
        List<ReconciliationMonthDetailDTO> dtos = FileUtil.readBuffer(file,ReconciliationMonthDetailDTO.class,FileUtil.SPLIT_COMMA);
        dtos.stream().forEach(it-> System.out.println(JSONObject.toJSONString(dtos)));

    }
    /**
     * sftp 对账(汇总对账)
     * 1.下载sftp文件(test:使用mockbean,替换为本地对账文件)
     * 2.读取对账文件,转换为javabean
     * 3.对账(todo:具体对账待实现)
     * @throws Exception
     */
    @Test
    public void reconciliationSummary() throws Exception {
        List<String>  list = fileSystemService.listFiles("/SZ-yuanshi/201906120002511010");
        System.out.println("文件列表:");
        System.out.println(list);
        File file0 = ResourceUtils.getFile("classpath:summaryComp.csv");

        Mockito.when(fileSystemService.downloadFile(Mockito.any())).thenReturn(file0);
        File file = fileSystemService.downloadFile("/SZ-yuanshi/201906120002511010/JYMX_201906120002511010_20190716.csv");
        List<ReconciliationSummaryDTO> dtos = FileUtil.readBuffer(file,ReconciliationSummaryDTO.class,FileUtil.SPLIT_S2);
        dtos.stream().forEach(it-> System.out.println(JSONObject.toJSONString(dtos)));

    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章