SpringBoot之远程调用的三大方式

为什么要使用远程调用?
SpringBoot不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。在Spring-Boot项目开发中,存在着本模块的代码需要访问外面模块接口,或外部url链接的需求, 比如在apaas开发过程中需要封装接口在接口中调用apaas提供的接口(像发起流程接口submit等等)下面也是提供了三种方式(不使用dubbo的方式)供我们选择。
方式一:使用原始httpClient请求

public static Map<String, String> httpPostRequest(String url, Map<String, Object> params, int timeout) {
        Map<String, String> resultMap = new HashMap<>();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "application/json");
            String s = Base64.getEncoder().encodeToString(getAuthorization().getBytes());

            log.info("getAuthorization():{}", s);
            httpPost.addHeader("authorization", "Basic " + s);
            StringEntity se = new StringEntity(JSONObject.toJSONString(params), "utf-8");
            se.setContentEncoding("UTF-8");
            se.setContentType("application/json");
            httpPost.setEntity(se);
            HttpResponse response = httpClient.execute(httpPost);
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout)
                    .setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
            httpPost.setConfig(requestConfig);
            HttpEntity responseEntity = response.getEntity();
            resultMap.put("scode", String.valueOf(response.getStatusLine().getStatusCode()));
            resultMap.put("data", "");
            if (responseEntity != null) {
                result = EntityUtils.toString(responseEntity, java.nio.charset.Charset.forName("UTF-8"));
                resultMap.put("data", result);
            }
        } catch (Exception e) {
            resultMap.put("scode", "error");
            resultMap.put("data", "HTTP请求失败: " + e.getMessage());
            Writer w = new StringWriter();
            e.printStackTrace(new PrintWriter(w));
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultMap;
    }

方式二:使用RestTemplate
先封装哥工具类吧

public class RestTemplateUtils {
    private static final RestTemplate REST_TEMPLATE;

    static {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        // 超时
        factory.setConnectTimeout(5000);
        factory.setReadTimeout(15000);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(createIgnoreVerifySSL(),
                // 指定TLS版本
                null,
                // 指定算法
                null,
                // 取消域名验证
                new HostnameVerifier() {
                    @Override
                    public boolean verify(String string, SSLSession ssls) {
                        return true;
                    }
                });
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        factory.setHttpClient(httpClient);
        REST_TEMPLATE = new RestTemplate(factory);
        // 解决中文乱码问题
        REST_TEMPLATE.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
    }

    public static RestTemplate getRestTemplate() {
        return REST_TEMPLATE;
    }

    /**
     * @param url    请求完整地址
     * @param method 请求方式
     * @param param  请求参数
     * @param cls    返回类型class
     * @param     泛型
     * @return
     */
    public static <T> T exchange(String url, HttpMethod method, Map param, Class<T> cls) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json;charset=UTF-8");
        return exchange(url, method, headers, param, cls);
    }

    public static <T> T exchange(String url, HttpMethod method, HttpHeaders headers, Map param, Class<T> cls) {
        String jsonMap = "";
        if (headers == null) {
            headers = new HttpHeaders();
            headers.add("Content-Type", "application/json;charset=UTF-8");
        }
        HttpEntity formEntity = new HttpEntity(param, headers);
        ResponseEntity<T> result = REST_TEMPLATE.exchange(url, method, formEntity, cls);
        logger.info("【Info-Http】Request:" + url + "--|--" + JSON.toJSONString(param) + "--|--Result:" + JSON.toJSONString(result));
        return result.getBody();
    }

    public static String exchange(String url, HttpMethod method, Map param) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json;charset=UTF-8");
        HttpEntity formEntity = new HttpEntity(param, headers);
        ResponseEntity<String> result = REST_TEMPLATE.exchange(url, method, formEntity, String.class);
        return result.getBody();
    }

    /**
     * 跳过证书效验的sslcontext
     *
     * @return
     * @throws Exception
     */
    private static SSLContext createIgnoreVerifySSL() {
        try {
            SSLContext sc = SSLContext.getInstance("TLS");

            // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
            X509TrustManager trustManager = new X509TrustManager() {
                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                               String paramString) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                               String paramString) throws CertificateException {
                }

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            sc.init(null, new TrustManager[]{trustManager}, null);
            return sc;
        } catch (Exception e) {
            log.info("建立 初始化异常");
            throw new RuntimeException();
        }

    }

方式三:使用Feign进行调用
1:主启动类添加
启动类上加上@EnableFeignClients

@SpringBootApplication
@EnableFeignClients
@ComponentScan(basePackages = {"com.xx.mp", "com.ap.*" ,"com.xdp.*"})
public class XxApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(XxApplication .class, args);
    }
 
}

2:此处编写接口模拟外部接口供feign调用外部接口方式使用
定义controller

@Autowired
PrintService printService;

@PostMapping("/outSide")
public String test(@RequestBody TestDto testDto) {
    return printService.print(testDto);
}

定义service

@Service
public interface PrintService {
    public String print(TestDto testDto);
}

定义serviceImpl

public class PrintServiceImpl implements PrintService {
 
    @Override
    public String print(TestDto testDto) {
        return "模拟外部系统的接口功能"+testDto.getId();
    }
}

构建Feigin的Service
定义service

//此处name需要设置不为空,url需要在.properties中设置
@Service
@FeignClient(url = "${outSide.url}", name = "service2")
public interface FeignService2 {
    @RequestMapping(value = "/custom/outSide", method = RequestMethod.POST)
    @ResponseBody
    public String getMessage(@Valid @RequestBody TestDto testDto);
}

定义controller

@Autowired
FeignService2 feignService2;
//测试feign调用外部接口入口
@PostMapping("/test2")
public String test2(@RequestBody TestDto testDto) {
    return feignService2.getMessage(testDto);
}

添加Header解决方法
将token等信息放入Feign请求头中,主要通过重写RequestInterceptor的apply方法实现
定义config

@Configuration
public class FeignConfig implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        //添加token
        requestTemplate.header("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ");
    }
}

以上的是SpringBoot之远程调用的三大方式 若需完整代码 可识别二维码后 给您发代码。
SpringBoot之远程调用的三大方式_第1张图片

你可能感兴趣的:(网络,websocket)