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

时间:2021-12-29 00:32:34

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

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

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

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

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

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

服务A action

?
1
2
3
4
5
6
7
@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 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//引入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

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

服务B api层 B-api

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@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层

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
   *
   * @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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
   * 接收参数传递
   * 分别接收下面三种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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
   *
   * @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);
   }

设置浏览器头

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
   * 根据不同的浏览器类型设置下载文件的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;
  }

总结

以上所述是小编给大家介绍的Spring cloud restTemplate 传递复杂参数的方式(多个对象),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!

原文链接:https://blog.csdn.net/u010920327/article/details/80042276