微服務的一些良好規範及實踐代碼記錄

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)));

    }

}

 

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