一、为什么要有转发

首先要了解跨域问题,此处不进行展开,总之 fate 框架不方便改且前端直接访问会产生跨域问题,所以写了一个中间件进行转发,服务之间的访问不会产生跨域,此外前端是部署在这个spring boot转发服务上的也不会产生跨域。

二、拿到一个 fate 的接口如何编写转发函数

通常是在这个文件中添加新接口
image.png
1.附带文件时,application-context为multipart,前端通过new FormData()来作为data

  1. @RequestMapping(value = "/predict/batch", method = RequestMethod.POST)
  2. @ResponseBody
  3. public ResponseResult getPredictBatch(
  4. @RequestPart(value = "service_id") String service_id,
  5. @RequestPart(value = "file") MultipartFile file,
  6. @RequestPart(value = "name") String name,
  7. @RequestPart(value = "context") String context,
  8. BindingResult bindingResult) {
  9. if (bindingResult.hasErrors()) {
  10. FieldError errors = bindingResult.getFieldError();
  11. return new ResponseResult<>(ErrorCode.ERROR_PARAMETER, errors.getDefaultMessage());
  12. }
  13. MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
  14. map.add("file", new FileSystemResource(convert(file)));
  15. map.add("service_id", service_id);
  16. map.add("context", context);
  17. map.add("name", name);
  18. HttpHeaders headers = new HttpHeaders();
  19. headers.setContentType(MediaType.MULTIPART_FORM_DATA);
  20. HttpEntity<MultiValueMap<String, Object>> request =
  21. new HttpEntity<MultiValueMap<String, Object>>(map, headers);
  22. Map map1;
  23. try {
  24. map1 = restTemplate.postForObject(fateUrl + Dict.URL_PREDICT_BATCH, request, Map.class);
  25. } catch (Exception e) {
  26. logger.error("connect fateflow error:", e);
  27. return new ResponseResult<>(ErrorCode.FATEFLOW_ERROR_CONNECTION, null);
  28. }
  29. if (!map1.get("retcode").equals(0)) {
  30. return new ResponseResult(ErrorCode.SERVLET_ERROR, map1);
  31. }
  32. return new ResponseResult<>(ErrorCode.SUCCESS, map1);
  33. }

类似于此接口,只需要把所有请求到的参数写到函数的参数中去
封装请求的参数和Header(文件需要通过convert函数转成File格式)
然后通过 RestTemplate(SpringBoot封装的网络请求工具)进行转发

2.不附带文件,直接把参数放在axios请求的的data中

  1. @RequestMapping(value = "/preprocess/data/cluster_data", method = RequestMethod.POST)
  2. @ResponseBody
  3. public ResponseResult postPreprocessClusterData(@RequestBody DataGetDTO dataGetDTO) {
  4. String result;
  5. try {
  6. result =
  7. httpClientPool.post(
  8. fateUrl + Dict.PREPROCESS_CLUSTER_DATA, JSON.toJSONString(dataGetDTO));
  9. } catch (Exception e) {
  10. logger.error("connect fateflow error:", e);
  11. return new ResponseResult<>(ErrorCode.FATEFLOW_ERROR_CONNECTION);
  12. }
  13. return ResponseUtil.buildResponse(result, null);
  14. }

代码格式固定,只需要自定义一个DTO文件作为参数即可,需要加get和set、构造函数等方法

  1. public class DataGetDTO implements Serializable {
  2. private String file_path;
  3. private String[] feature;
  4. private String y_feat;
  5. private String y_feature;
  6. private String[] x_feat;
  7. private int n;
  8. ....
  9. }

这里如果参数是一个对象(前端概念中的对象,这里指json格式),类型设置为 JSONObject

3.转发的路径和请求的路径需要保持一致,要在DICT文件中配置
image.png
image.png

三、关于访问路径

在application.yml中进行配置
image.png
正式上线后需要打开第三个注解(严格来说需要写三个配置文件,然后配置参数决定使用哪个配置文件,此处是为了方便开发)