Spring cloud restTemplate 传递复杂参数(多个对象)

使用微服务的时候往往服务之间调用比较麻烦,spring cloud提供了Feign接口调用, RestTemplate调用的方式

这里我探讨下RestTemplate调用的方式:

服务A:接收三个对象参数 这三个参数的是通过数据库查询出来的

服务B:要调用服务A 服务B提供了查询三个参数的方法,后面要使用三个参数

对于服务A,处理的方式有两中

1. 服务B提供一个Feign接口将查询三个参数的方法公开,服务A直接引用Feign来查询参数,服务B只需要将三个查询关键字传递过去即可

服务A action

    @PostMapping("/import/{busiCode}/{filePath}")
    public Map<String,String> importExcel(@PathVariable("filePath") String filePath,@PathVariable("busiCode") String busiCode,@RequestBody Map<String, String> params,
                                          HttpServletRequest request,HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        UserInfo user = UserUtil.getUser();
        return excelService.importExcel(filePath,busiCode,params,user);
    }

服务A service

//引入Feign接口
private ExcelFreign excelFreign;

public Map<String,String> importExcel(String filePath, String busiCode,Map<String, String> params,UserInfo user )  {
		Map<String,String> result=new HashMap<String,String>();
		excelFreign = SpringTool.getApplicationContext().getBean(ExcelFreign.class);
		CmdImportConfigDto configDto = excelFreign.getCmdImportConfigByBusiCode(busiCode);
		CmdImportDto importDto=new CmdImportDto();
		importDto.setImportConfigId(configDto.getId());
		importDto.setExcelPath(filePath);
		importDto.setParam(new GsonBuilder().create().toJson(params));
		importDto.setLog("");
		Long impId=null;
		try {
			impId= Long.valueOf(excelFreign.saveCmdImportDto(importDto));
		} catch (Exception e1) {
			e1.printStackTrace();
			result.put("error", "保存出现异常");
			result.put("message", e1.getMessage());
			return result;
		}
		try{
			excelFreign.updateImportStatus(impId, ImportConstant.ImportStatus.SUBMIT, "提交成功");
		}catch(Exception e){
				e.printStackTrace(); 
		}
		ValidateTask validateTask=new ValidateTask();
		validateTask.init(impId,filePath, busiCode, params,user);
		String message;
		try {
			message = validateTask.call();
		} catch (Exception e) {
			e.printStackTrace();
			result.put("error", "验证出现异常");
			result.put("message", e.getMessage());
			return result;
		}
		if(message!=null){
			result.put("error", "验证不通过");
			result.put("message", message);
			return result;
		}
		PersistTask persistTask=new PersistTask();
		persistTask.init(impId,filePath, busiCode, params,user);
		result.putAll(ImportQueue.submit(persistTask));
		return result;
	}

服务B 提供的B-Fegin

@FeignClient(value = "frame-service",path = "/excelApi/v1")
public interface ExcelFreign extends ExcelApi {

}

服务B api层 B-api

public interface ExcelApi {
/**
     * 更新状态
     * @param impId
     * @param importType
     * @param result
     */
    @PostMapping("/updateImportStatus/{impId}/{importType}/{result}")
    void updateImportStatus(@PathVariable("impId") Long impId, @PathVariable("importType") String importType, @PathVariable("result") String result) throws Exception;
/**
     * 获取导入配置项
     * @param busiCode
     * @return
     */
    @GetMapping("/getImportConfig/{busicode}")
    CmdImportConfigDto getCmdImportConfigByBusiCode(@PathVariable("busicode") String busiCode);

    /**
     * 保存信息
     * @param importDto
     * @return
     */
    @PostMapping("/saveImport")
    String saveCmdImportDto(@RequestBody CmdImportDto importDto);
}

服务B 实现api接口的action

@RestController
@RequestMapping("/excelApi/v1")
public class ExcelFeignAction implements ExcelApi {
@Autowired
    private  CmdExportService exportService;
 /**
     * 获取导入配置项
     * @param busiCode
     * @return
     */
    @GetMapping("/getImportConfig/{busicode}")
    public CmdImportConfigDto getCmdImportConfigByBusiCode(@PathVariable("busicode") String busiCode){
        return cmdImportConfigService.getCmdImportConfigByBusiCode(busiCode);
    }
 /**
     * 更新状态
     * @param impId
     * @param importStatus
     * @param result
     */
    @PostMapping("/updateImportStatus/{impId}/{importType}/{result}")
    public void updateImportStatus(@PathVariable("impId") Long impId, @PathVariable("importType") String importStatus, @PathVariable("result") String result) throws Exception{
        cmdImportService.updateImportStatus(impId,importStatus,new Date() , result);
    }
/**
     * 保存信息
     * @param importDto
     * @return
     */
    @PostMapping("/saveImport")
    public String saveCmdImportDto(@RequestBody CmdImportDto importDto){
        try{
            cmdImportService.saveCmdImportDto(importDto);
           return importDto.getId();
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessRuntimeException("系统出现异常");
        }

    }
}

服务B 调用服务A  action层

/**
     *
     * @param busicode  导出的业务编码 能确定某个模块做导出操作
     * @param values  请求参数
     *
     *                通过restTemplate 传递复杂参数
     * @return
     *  返回 文件流 让浏览器弹出下载 
     */
    @PostMapping(value = "/export/v3/{busicode}")
    @ResponseBody
    public ResponseEntity<byte[]> expDownLoadV3(@PathVariable("busicode") String busicode , @RequestBody Map<String,Object> values, HttpServletRequest request)throws Exception {
      if(StringUtils.isBlank(busicode)){
            throw new BusinessRuntimeException("参数错误,请检查参数是否正确,busicode ?");
        }
        // 获取执行过程
        Map map = restTemplate.postForObject("http://" + serviceId + "/excelApi/v1/文件名"/"+busicode,values,Map.class);
        String path = (String)map.get("filepath");
        byte[] excel = FastDFSClient.downloadToBytes(path);
        CmdExportConfigDto cmdExportConfig = exportService.getCmdExportConfigByBusiCode(busicode);
        //获取文件名
        String fileName = cmdExportConfig.getReportName();
        // 获取文件后缀名
        String extFileName = path.substring(path.lastIndexOf('.')+1);
        HttpHeaders headers = new HttpHeaders();
        // 获取用户浏览器的种类  对不同的浏览器进行编码处理
        final String userAgent = request.getHeader("USER-AGENT");
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", FrameUrlConstants.transFromFileName(userAgent,fileName) + "." + extFileName);
        return new ResponseEntity<byte[]>(excel,headers,HttpStatus.OK);
    }

2.服务B将查询出来的参数直接传递给服务A

服务A:

/**
     * 接收参数传递
     * 分别接收下面三种key value的键值对
     * cmdExportConfig:CmdExportConfigDto
     * exportFieldList:List<CmdExportFieldConfigDto>
     * params:Map
     * @param params
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/export/v2")
    public ResponseEntity exportExcel(@RequestBody Map<String,Object> params,HttpServletRequest request,HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        try {
            // 将文件的路径获取到
            ObjectMapper mapper = new ObjectMapper();
            LinkedHashMap requestParMap = (LinkedHashMap)params.get("cmdExportConfig");
            CmdExportConfigDto cmdExportConfigDto = null;
            List<CmdExportFieldConfigDto> exportFieldList = null;
            if(requestParMap.size()>0){
                cmdExportConfigDto = mapper.convertValue(requestParMap,CmdExportConfigDto.class);
            }
            ArrayList arrayList = (ArrayList)params.get("exportFieldList");

            if(arrayList.size()>0){
                exportFieldList = mapper.convertValue(arrayList, new TypeReference<CmdExportFieldConfigDto>() {});
            }
            Map values =  (Map)params.get("params");
            String filePath = excelService.exportExcel(cmdExportConfigDto,exportFieldList,params,request.getServletContext().getRealPath("/"));
            Map<String,String> map = new HashMap<String, String>();
            map.put("filepath", filePath);
            return new ResponseEntity(map,HttpStatus.OK);
        }catch (IOException e){
            throw new RuntimeException("输出文件出错");
        }

    }

服务B:

/**
     * 
     * @param busicode  导出的业务编码 能确定某个模块做导出操作
     * @param values  请求参数
     *
     *                通过restTemplate 传递复杂参数
     * @return
     *  返回 文件流 让浏览器弹出下载  目前需要解决 将字节流响应到浏览器的控制台了 后面均采用url下载的方式
     */
    @PostMapping(value = "/export/v3/{busicode}",produces = MediaType.TEXT_PLAIN_VALUE)
    @ResponseBody
    public ResponseEntity<byte[]> expDownLoadV3(@PathVariable("busicode") String busicode , @RequestBody Map<String,Object> values, HttpServletRequest request)throws Exception {
        String busiCode = values.get("busiCode").toString();
        if(StringUtils.isBlank(busiCode)){
            throw new BusinessRuntimeException("参数错误,请检查参数是否正确,busiCode ?");
        }
        // 获取执行过程
        Map map = excuteRestTemplate(busiCode,values);
        String path = (String)map.get("filepath");
        byte[] excel = FastDFSClient.downloadToBytes(path);
        CmdExportConfigDto cmdExportConfig = exportService.getCmdExportConfigByBusiCode(busiCode);
        //获取文件名
        String fileName = cmdExportConfig.getReportName();
        // 获取文件后缀名
        String extFileName = path.substring(path.lastIndexOf('.')+1);
        HttpHeaders headers = new HttpHeaders();erAgent = request.getHeader("USER-AGENT");
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", FrameUrlConstants.transFromFileName(userAgent,fileName) + "." + extFileName);

        return new ResponseEntity<byte[]>(excel,headers,HttpStatus.OK);
    }

    /**
     * 执行请求调用
     * @param busiCode
     * @param variables
     * @return
     */
     private Map excuteRestTemplate(String busiCode,Map variables){
         String serviceId="";
         //查询导出配置
         CmdExportConfigDto cmdExportConfig = exportService.getCmdExportConfigByBusiCode(busiCode);
         serviceId = cmdExportConfig.getSystemType();
         if(cmdExportConfig==null){
             throw new BusinessRuntimeException("没有导出配置无法导出");
         }
         //根据导出配置id获取导出字段信息
         List<CmdExportFieldConfigDto> exportFieldList = exportService.getAllCmdExportFieldConfigDtoByConfigId(cmdExportConfig.getId());

         if(StringUtils.isBlank(serviceId)){
             throw new BusinessRuntimeException("未配置导出的服务");
         }
         Map<String, Object> uriVariables = new HashMap<>();
         uriVariables.put("cmdExportConfig",cmdExportConfig);
         uriVariables.put("exportFieldList",exportFieldList);
         uriVariables.put("params",variables);
        return restTemplate.postForObject("http://" + serviceId + "/excelService/export/v2",new HttpEntity(uriVariables),Map.class);
     }

设置浏览器头

/**
     * 根据不同的浏览器类型设置下载文件的URL编码
     * @param userAgent
     * @param fileName
     * @return
     * @throws Exception
     */
    public static String transFromFileName(String userAgent,String fileName) throws Exception{
        String finalFileName = "";

        if(StringUtils.contains(userAgent, "MSIE")){//IE浏览器
            finalFileName = URLEncoder.encode(fileName,"UTF-8");
        }else if(StringUtils.contains(userAgent, "Mozilla")){//google,火狐浏览器
            finalFileName = new String(fileName.getBytes("GBK"), "ISO8859-1");
        }else{
            finalFileName = URLEncoder.encode(fileName,"UTF-8");//其他浏览器
        }
        return finalFileName;
    }
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值