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;

}

总结

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

以上是 Spring cloud restTemplate 传递复杂参数的方式(多个对象) 的全部内容, 来源链接: utcz.com/z/342317.html

回到顶部