赞
踩
Feign 是一个在 Java 平台上的声明式、模板化的 HTTP 客户端,它简化了使用 HTTP API 的过程。Feign 是 Netflix 开发的,旨在简化基于 HTTP 的 API 客户端开发。
1.1:声明式 API 定义: 通过接口和注解的方式定义 API,使得 API 定义更加清晰和简洁。
1.2:集成 Ribbon: Feign 默认集成了 Ribbon 负载均衡器,可以轻松实现客户端的负载均衡。
1.3:集成 Hystrix: Feign 也可以集成 Hystrix,从而实现客户端的容错和断路器功能。
1.4:支持多种编码器和解码器: Feign 支持多种编码器和解码器,包括 JSON、XML 等。
1.5:支持动态 URL 和查询参数: 可以在接口方法中直接使用参数来构建 URL 和查询参数。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
@Slf4j//日志log
@SpringBootApplication//用于标识 Spring Boot 应用程序的注解
@EnableFeignClients//开启feign
@MapperScan("com.netrust.*.dao")//扫描包下的mapper
@EnableTransactionManagement//开启事务注解
public class BaseApplication {
public static void main(String[] args) {
SpringApplication.run(BaseApplication.class, args);
}
}
@FeignClient(value = ServerNameConstants.SYSTEM_BASE, contextId = "room", configuration = FeignConfiguration.class) public interface FeignApi { @PostMapping("/add") String addSysApi(@RequestBody FeignBO feignBO); @PutMapping("/edit") String editSysApi(@RequestBody FeignBO feignBO); @DeleteMapping("/delete") String deleteByIdSysApi(@RequestBody FeignDto feignDto); @GetMapping("/queryById")//@SpringQueryMap表示get可以用对象接收,不然就需要一个一个接收 String queryById(@SpringQueryMap FeignDto feignDto); @RequestMapping(value = "file/personPhotoUpload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) String personPhotoUpload(@RequestPart(value = "file") MultipartFile file, @RequestParam(value = "moduleName") String moduleName, @RequestParam(value = "functionName") String functionName, @RequestParam(value = "needCompress") Boolean needCompress); }
@Resource
private FeignApi feignApi;
/**
* 通过主键查询单条数据
*/
@GetMapping("/feign/{id}")
@ApiOperation(value = "通过主键查询单条数据")
public ResultJson queryById( FeignDto feignDto, @PathVariable("id") Long id) {
feignDto.setId(id);
String s = feignApi.queryById(feignDto);
return JSONObject.parseObject(s, ResultJson.class);
}
2.5.1、value: 指定要调用的目标服务的服务名。可以是一个单独的服务名,也可以是多个服务名组成的数组。
2.5.2、url: 指定要调用的目标服务的URL地址,可以是一个完整的URL地址,也可以是占位符形式的URL地址。
2.5.3、path: 指定要调用的目标服务的基本路径,可以是一个字符串,也可以是一个占位符形式的字符串。
2.5.4、configuration: 指定要使用的Feign客户端配置类。可以自定义配置Feign客户端的行为。
2.5.5、decode404: 指定是否将404错误解码。默认情况下,Feign会将404错误解码为null值。
2.5.6、fallback: 指定一个回退类,当调用失败时,将调用回退类中的方法。回退类必须实现@FeignClient注解中的接口。
2.5.7、fallbackFactory: 指定一个回退工厂类,用于创建回退类的实例。回退工厂类必须实现FallbackFactory接口。
2.5.8、primary: 指定Feign客户端是否为首选客户端。如果设置为true,则优先使用该客户端。
2.5.9、qualifier: 指定Feign客户端的限定符。可以与@Autowired注解配合使用,用于指定要注入的Feign客户端实例。
2.5.10、name: 同value,指定要调用的目标服务的服务名。
2.5.11、contextId: 指定Feign客户端的上下文ID。用于区分不同的Feign客户端实例。
2.5.12、url: 指定要调用的目标服务的URL地址。
@Slf4j public class HttpClientUtils { /** * 文件上传到第三方 * @param url 网络地址 * @param inputStream 文件流 * @param headers 头文件(认证信息设置) * @param verification 是否需要验证 * @return * @throws IOException */ public static String uploadFile(String url, InputStream inputStream, Map<String, String> headers, boolean verification) throws IOException { HttpClient httpClient = verification ? HttpClients.createDefault() : wrapClient(); HttpPost httpPost = new HttpPost(url); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpPost.setConfig(requestConfig); if (headers != null) { headers.forEach((key, value) -> { httpPost.setHeader(key, value); }); } //创建文件把流文件写入到字节内 File file = File.createTempFile(UUID.randomUUID().toString(), ".jpg"); FileOutputStream os = new FileOutputStream(file); int read = 0; byte[] buffer = new byte[1024]; while ((read = inputStream.read(buffer, 0, 1024)) != -1) { os.write(buffer, 0, read); } inputStream.close(); //发送邮件 MultipartEntityBuilder builder = MultipartEntityBuilder.create(); FileBody fileBody = new FileBody(file, ContentType.MULTIPART_FORM_DATA); builder.addPart("file", fileBody); httpPost.setEntity(builder.build()); HttpResponse response = httpClient.execute(httpPost); String httpEntityContent = getHttpEntityContent(response); httpPost.abort(); return httpEntityContent; } /** * 封装HTTP POST方法 * * @param verification TRUE为不跳过证书检测 FALSE为跳过证书检测 * @param (如JSON串) * @return * @throws ClientProtocolException * @throws IOException */ public static String post(String url, String body, Map<String, String> headers, boolean verification) throws ClientProtocolException, IOException { HttpClient httpClient = verification ? HttpClients.createDefault() : wrapClient(); HttpPost httpPost = new HttpPost(url); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpPost.setConfig(requestConfig); httpPost.setHeader("Content-Type", "application/json"); if (headers != null) { headers.forEach((key, value) -> { httpPost.setHeader(key, value); }); } if (body != null) { StringEntity s = new StringEntity(body, StandardCharsets.UTF_8); s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); //设置参数到请求对象中 httpPost.setEntity(s); } HttpResponse response = httpClient.execute(httpPost); String httpEntityContent = getHttpEntityContent(response); httpPost.abort(); return httpEntityContent; } public static String put(String url, String body, Map<String, String> headers, boolean verification) throws ClientProtocolException, IOException { HttpClient httpClient = verification ? HttpClients.createDefault() : wrapClient(); HttpPut httpPut = new HttpPut(url); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpPut.setConfig(requestConfig); httpPut.setHeader(HTTP.CONTENT_TYPE, "application/json"); if (headers != null) { headers.forEach((key, value) -> { httpPut.setHeader(key, value); }); } if (body != null) { StringEntity s = new StringEntity(body, StandardCharsets.UTF_8); s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); //设置参数到请求对象中 httpPut.setEntity(s); } HttpResponse response = httpClient.execute(httpPut); String httpEntityContent = getHttpEntityContent(response); httpPut.abort(); return httpEntityContent; } public static String delete(String url, String body, Map<String, String> headers, boolean verification) throws ClientProtocolException, IOException { HttpClient httpClient = verification ? HttpClients.createDefault() : wrapClient(); HttpDeleteWithBody httpDelete = new HttpDeleteWithBody(url); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpDelete.setConfig(requestConfig); httpDelete.setHeader(HTTP.CONTENT_TYPE, "application/json"); if (headers != null) { headers.forEach((key, value) -> { httpDelete.setHeader(key, value); }); } if (body != null) { StringEntity s = new StringEntity(body, StandardCharsets.UTF_8); s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); //设置参数到请求对象中 httpDelete.setEntity(s); } HttpResponse response = httpClient.execute(httpDelete); String httpEntityContent = getHttpEntityContent(response); httpDelete.abort(); return httpEntityContent; } /** * 封装HTTP GET方法 * * @param * @param verification TRUE为不跳过证书检测 FALSE为跳过证书检测 * @return * @throws ClientProtocolException * @throws IOException */ public static String get(String url, Map<String, Object> params, Map<String, String> headers, boolean verification) throws ClientProtocolException, IOException { HttpClient httpClient = verification ? HttpClients.createDefault() : wrapClient(); HttpGet httpGet = new HttpGet(); //设置请求和传输超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); httpGet.setConfig(requestConfig); if (headers != null) { headers.forEach((key, value) -> { httpGet.addHeader(key, value); }); } if (params != null) { url = getUrlByParams(url, params); } httpGet.setURI(URI.create(url)); HttpResponse response = httpClient.execute(httpGet); String httpEntityContent = getHttpEntityContent(response); httpGet.abort(); return httpEntityContent; } private static String getUrlByParams(String url, Map<String, Object> params) { StringBuffer sb = new StringBuffer(); params.forEach((key, value) -> { sb.append("&" + key + "=" + value); }); if (sb.length() > 0) { String substring = sb.substring(1); url += url.contains("?") ? "&" : "?" + substring; } return url; } /** * 获得响应HTTP实体内容 * * @param response * @return * @throws IOException * @throws UnsupportedEncodingException */ private static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException { HttpEntity entity = response.getEntity(); if (entity != null) { InputStream is = entity.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String line = br.readLine(); StringBuilder sb = new StringBuilder(); while (line != null) { sb.append(line + "\n"); line = br.readLine(); } return sb.toString(); } return null; } public static HttpClient wrapClient() { HttpClients.createDefault(); try { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager trustManager = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } }; ctx.init(null, new TrustManager[]{trustManager}, null); SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE); return HttpClients.custom() .setSSLSocketFactory(ssf) .build(); } catch (Exception e) { return HttpClients.createDefault(); } } }
try { HashMap<String, String> map = new HashMap<>(); map.put("app_id",appid); map.put("app_secret",appSecret); map.put("grant_type","client_credentials"); String res = HttpClientUtils.post(host + "/oauth/token", JSON.toJSONString(map), null, false); JSONObject jsonObject = JSONObject.parseObject(res); if(jsonObject.containsKey("code") && jsonObject.getString("code").equals("0")){ return JSONObject.parseObject(jsonObject.getString("result"),PushToken.class); }else{ throw new ServiceException(res); } }catch (ServiceException e){ throw new ServiceException(e); }catch (Exception e){ e.printStackTrace(); }
@Slf4j @Component public class RoutingDelegateUtil { @Resource //@Qualifier(value = "remoteRestTemplate") private RestTemplate restTemplate; /** * 上传form表单,文件 */ private final static String CONTENT_TYPE_FORM = "multipart/form-data;"; /** * 请求转发统一处理 * * @param request 原请求对象 * @param routeUrl 路由地址,统一前缀,重定向目标主机域名(带协议及端口) * @param prefix 需要去除的前缀 * @return * @throws Exception */ public ResponseEntity<String> redirect(HttpServletRequest request, String routeUrl, String prefix) throws Exception { String contentType = request.getContentType(); log.info("getContentType={}", contentType); // multipart/form-data处理 if (StringUtils.isNotEmpty(contentType) && contentType.contains(CONTENT_TYPE_FORM)) { return redirectFile(request, routeUrl); } else { return redirect(request, routeUrl, prefix, String.class); } } /** * 上传form表单,文件 * <p> * 请求转发处理 * * @param request 原请求对象 * @param routeUrl 重定向目标主机域名(带协议及端口) * @return * @throws IOException */ public ResponseEntity<String> redirectFile(HttpServletRequest request, String routeUrl) throws IOException { // build up the redirect URL String redirectUrl = createRedictUrl(request, routeUrl, ""); log.info("redirectFile redirectUrl={}", redirectUrl); String method = request.getMethod(); //设置请求头 MultiValueMap<String, String> headers = parseRequestHeader(request); // 组装form参数 MultiValueMap<String, Object> form = new LinkedMultiValueMap<>(); StandardMultipartHttpServletRequest standardMultipartHttpServletRequest = (StandardMultipartHttpServletRequest) request; // 组装form参数-文件 MultiValueMap<String, MultipartFile> multiValueMap = standardMultipartHttpServletRequest.getMultiFileMap(); for (Map.Entry<String, List<MultipartFile>> entries : multiValueMap.entrySet()) { for (MultipartFile multipartFile : entries.getValue()) { String fileName = multipartFile.getOriginalFilename(); log.info("redirectFile MultipartFile: fileName={}", fileName); File file = File.createTempFile("spw-", fileName); multipartFile.transferTo(file); FileSystemResource fileSystemResource = new FileSystemResource(file); form.add(entries.getKey(), fileSystemResource); } } // 组装form参数-一般属性 Enumeration<String> enumeration = standardMultipartHttpServletRequest.getParameterNames(); while (enumeration.hasMoreElements()) { String name = enumeration.nextElement(); String value = standardMultipartHttpServletRequest.getParameter(name); log.info("redirectFile enumeration: name={}, value={}", name, value); form.add(name, value); } // 用HttpEntity封装整个请求报文 HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(form, headers); return restTemplate.exchange(redirectUrl, HttpMethod.valueOf(method), formEntity, String.class); } /** * 非form-data请求转发处理 * * @param request 原请求对象 * @param routeUrl 重定向目标主机域名(带协议及端口) * @param prefix 需要去除的前缀 * @param clazz 结果类型 * @return * @throws Exception */ public <T> ResponseEntity<T> redirect(HttpServletRequest request, String routeUrl, String prefix, Class<T> clazz) throws Exception { // build up the redirect URL String redirectUrl = createRedictUrl(request, routeUrl, prefix); log.info("redirectUrl={}", redirectUrl); RequestEntity requestEntity = createRequestEntity(request, redirectUrl); return restTemplate.exchange(requestEntity, clazz); } /** * 构建重定向地址 * * @param request 原请求对象 * @param routeUrl 重定向目标主机域名(带协议及端口) * @param prefix 需要去除的前缀 * @return */ private String createRedictUrl(HttpServletRequest request, String routeUrl, String prefix) { String queryString = request.getQueryString(); return routeUrl + request.getRequestURI().substring(1).replace(prefix, "") + (queryString != null ? "?" + queryString : ""); } /** * 构建请求实体 * * @param request 原请求对象 * @param url 新目标路由URL * @return * @throws URISyntaxException * @throws IOException */ private RequestEntity createRequestEntity(HttpServletRequest request, String url) throws URISyntaxException, IOException { String method = request.getMethod(); HttpMethod httpMethod = HttpMethod.resolve(method); MultiValueMap<String, String> headers = parseRequestHeader(request); byte[] body = parseRequestBody(request); return new RequestEntity<>(body, headers, httpMethod, new URI(url)); } /** * 解析请求体 * * @param request * @return * @throws IOException */ private byte[] parseRequestBody(HttpServletRequest request) throws IOException { InputStream inputStream = request.getInputStream(); return StreamUtils.copyToByteArray(inputStream); } /** * 解析请求头 * * @param request * @return */ private MultiValueMap<String, String> parseRequestHeader(HttpServletRequest request) { HttpHeaders headers = new HttpHeaders(); List<String> headerNames = Collections.list(request.getHeaderNames()); for (String headerName : headerNames) { List<String> headerValues = Collections.list(request.getHeaders(headerName)); for (String headerValue : headerValues) { headers.add(headerName, headerValue); } } return headers; } }
@RequestMapping("/sys-monitor/**")
@Description("服务监控分发")
public ResultJson transmit(HttpServletRequest request, @RequestParam(value = "ip", required = false, defaultValue = "127.0.0.1") String ip) throws Exception {
String routeUrl = "http://" + ip + ":端口";
ResponseEntity<ResultJson> responseEntity = restRoute.redirect(request, routeUrl, "sys-monitor", ResultJson.class);
return responseEntity.getBody();
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。