问题
- 跨服务调用 feign方法
- 调用第三方接口 resttemplate方法
解决方法
- feign
- 首先是feign的跨服务调用,这是controller层的代码
@Permission(permissionLogin = true)
@ApiOperation("feign调用示例接口")
@PostMapping(value = "/feign")
public ResponseEntity<ReturnMessage> feign(@RequestBody List<feignVO> feignVOS) {
ResponseEntity<FeignRunInfo> feignResult = feignToService.insert(feignVOS);
ReturnMessage<FeignRunInfo> returnMessage = new ReturnMessage();
if (feignResult != null && feignResult.hasBody()) {
FeignRunInfo feignRunInfo = feignResult.getBody();
returnMessage.feignStatus(feignRunInfo.noErrorMsg(), feignRunInfo);
}
return new ResponseEntity<>(returnMessage, HttpStatus.OK);
}
其实是有封装了返回的数据,所以会比较繁琐,本来没有那么多代码的。
- 进到服务层,要注意服务层的代码需要加注解
@FeignClient
/**
* 〈跨服务调用〉
*/
@FeignClient(value = "feignTo-service", fallbackFactory = FeignFeignToFallBackFactory.class)
public interface IFeignFeignToService {
/**
* [接口] 数据接口
*
* @param feignVOS 新增的数据
* @return 返回状态数据
*/
@PostMapping(value = "/insert") //调用的接口地址
ResponseEntity<FeignRunInfo> insert(@RequestBody List<FeignVO> feignVOS);
}
实现类
@Component
public class FeignFeignToFallBackFactory implements FallbackFactory<IFeignFeignToService> {
private static final String ERROR_MSG = "An error occurs at run time.";
@Override
public IFeignFeignToService create(Throwable cause) {
return new IFeignFeignToService() {
@Override
public ResponseEntity<FeignRunInfo> insert(List<FeignVO> feignVOS) {
FeignRunInfo feignRunInfo = new FeignRunInfo();
feignRunInfo.setErrorMsg(ERROR_MSG);
return new ResponseEntity<>(feignRunInfo, HttpStatus.OK);
}
};
}
}
这样就实现了feign跨服务调用。
有几个需要注意的点:
- 调用的接口和待调用的接口数据需一致
- 在本地调试时需要两个服务都起起来
- resttemplate
- 笔者这边调用墨迹天气的接口,控制层代码,通过经纬度查询某地天气,这里的
url
做了一个变量处理,如果要改第三方接口地址,也是可以改的。
/**
* 〈天气〉
*
* @author GuoYongQin
* @create 2018/10/24
* @since 1.0.0
*/
@RestController
@RequestMapping(value = "/v1/api/weather")
public class WeatherController {
@Autowired
private IWeatherService weatherService;
@Permission(permissionLogin = true)
@ApiOperation(value = "weather接口")
@RequestMapping(value = "/weather", method = RequestMethod.GET)
public ResponseEntity<MoJiWeatherBO> weather(@RequestParam String url,
@RequestParam Double longitude,
@RequestParam Double latitude) {
return new ResponseEntity<>(weatherService.moJiWeather(code, longitude, latitude), HttpStatus.OK);
}
}
- 进到服务接口
public interface IWeatherService {
MoJiWeatherBO moJiWeather(String url, Double longitude, Double latitude);
}
- 实现类
@Service
public class WeatherServiceImpl implements IWeatherService {
@Autowired
private RestTemplate restTemplate;
String url = "http://aliv8.data.moji.com/whapi/json/aliweather/forecast15days";
String token = "7538f7246218bdbf795b329ab09cc524";
@Override
public MoJiWeatherBO moJiWeather(String url, Double longitude, Double latitude) {
String weatherInfo = null;
weatherInfo = requestWeatherInfo(url, longitude, latitude);
if (weatherInfo != null) {
return JSONObject.parseObject(weatherInfo, MoJiWeatherBO.class);
} else {
return new MoJiWeatherBO();
}
}
private String requestWeatherInfo(String url, Double longitude, Double latitude) {
try {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/x-www-form-urlencoded");
headers.add("Authorization", "APPCODE c4cb20e0631c4fa49335860c2195c47e");
MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
postParameters.add("lon", safeToString(longitude));
postParameters.add("lat", safeToString(latitude));
postParameters.add("token", token);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(postParameters, headers);
ResponseEntity<String> result = restTemplate.postForEntity(url, requestEntity, String.class);
return result.getBody();
} catch (RestClientException e) {
return null;
}
}
private String safeToString(Object object) {
return (object == null ? "" : object.toString());
}
}
这样就实现了rest template第三方接口跨服务调用。
总结
rest template我在网上看到的资料不多,毕竟可以直接用http请求方法,不过这种方法也可以试试。