目录
前言
1.引入openfeign相关依赖
2.开启openFeign远程调用,在启动类头加上注解即可
3. 提供远程调用接口,接口名称必须与controler名称保持一致
4.远程调用关键代码
4.1 注入restTemplate
4.2 配置拦截器
4.3 设置请求头
4.4 获取请求结果
4.5 远程调用的完整代码:
5.实现效果
前言
因为其他各个服务都做了授权认证,如果不带Authorization,或者无效的请求头Authorization,都无法通过验证,即请求接口失败。
1.引入openfeign相关依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>3.0.0</version></dependency><
2.开启openFeign远程调用,在启动类头加上注解即可
3. 提供远程调用接口,接口名称必须与controler名称保持一致
4.远程调用关键代码
4.1 注入restTemplate
package com.example.mq.config;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.common.interpretor.AuthorizationHeaderInterceptor;
import com.example.securityservice.config.ResourceServerConfig;
import com.example.securityservice.config.TokenConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;/*** 通过扫描包的方式注入注解,降低代码的耦合度*/
@ComponentScan(basePackages = "com.example.securityservice.config")
@Configuration
public class LoadAuthorizationConfig {private Logger logger = LoggerFactory.getLogger(LoadAuthorizationConfig.class);@Beanpublic RestTemplate restTemplate(){RestTemplate restTemplate = new RestTemplate();return restTemplate;}}
4.2 配置拦截器
在远程调用的请求头加入 Authorization请求头,降低代码的重复率。
package com.example.mq.interpretor;import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;import java.io.IOException;/*** 请求拦截器,在restTemplate请求中自动加入token*/public class AuthorizationHeaderInterceptor implements ClientHttpRequestInterceptor {private final String token;public AuthorizationHeaderInterceptor(String token) {this.token = token;}@Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {// 添加Authorization头request.getHeaders().add("Authorization", "Bearer " + this.token);// 如果需要,还可以添加其他请求头// request.getHeaders().add("Another-Header", "HeaderValue");return execution.execute(request, body);}
}
4.3 设置请求头
public void setHeaderToken(){// 创建MultiValueMap来存储表单数据MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();formData.add("client_id", CLIENT_ID);formData.add("client_secret", CLIENT_SECRET);formData.add("grant_type", GRANT_TYPE);// 设置请求头,指明内容类型为application/x-www-form-urlencodedHttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);// 创建HttpEntity,它包装了表单数据和请求头HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);// 发送POST请求Object response = restTemplate.postForObject(TOKEN_REQUEST_URL, requestEntity, Object.class);JSONObject jsonObject = JSON.parseObject(JSONObject.toJSONString(response));String access_token = jsonObject.getString("access_token");// 创建拦截器AuthorizationHeaderInterceptor interceptor = new AuthorizationHeaderInterceptor(access_token);// 将拦截器添加到RestTemplaterestTemplate.getInterceptors().add(interceptor);}
4.4 获取请求结果
public Object getReqRes(String path){ServiceInstance services= discoveryClient.getInstances("consumer-service").get(0);String host = services.getHost();int port = services.getPort();StringBuffer reqUrl = new StringBuffer();reqUrl.append("http://");reqUrl.append(host);reqUrl.append(":"+port);String res = restTemplate.getForObject(reqUrl.toString()+path,String.class);return res;}
4.5 远程调用的完整代码:
package com.example.mq.controller;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.common.interpretor.AuthorizationHeaderInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;@RestController
@RequestMapping("/mq")
public class MqController {@Autowiredprivate RestTemplate restTemplate;private final static String CLIENT_ID ="admin";private final static String CLIENT_SECRET ="123456";private final static String GRANT_TYPE ="client_credentials";private final static String TOKEN_REQUEST_URL ="http://localhost:8063/oauth/token";private final static String URL ="http://localhost:8063";private Logger logger = LoggerFactory.getLogger(MqController.class);@Autowiredprivate DiscoveryClient discoveryClient;@GetMapping("/qq")public String mq(){//设置请求头setHeaderToken();//发起请求Object reqUrl = getReqRes("/consumer");logger.info("请求结果:{}",JSON.toJSONString(reqUrl));return "mq";}@PreAuthorize("hasAuthority('system:dept:list')")@GetMapping("/mm")public String mm(){return "mm";}public void setHeaderToken(){// 创建MultiValueMap来存储表单数据MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();formData.add("client_id", CLIENT_ID);formData.add("client_secret", CLIENT_SECRET);formData.add("grant_type", GRANT_TYPE);// 设置请求头,指明内容类型为application/x-www-form-urlencodedHttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);// 创建HttpEntity,它包装了表单数据和请求头HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);// 发送POST请求Object response = restTemplate.postForObject(TOKEN_REQUEST_URL, requestEntity, Object.class);JSONObject jsonObject = JSON.parseObject(JSONObject.toJSONString(response));String access_token = jsonObject.getString("access_token");// 创建拦截器AuthorizationHeaderInterceptor interceptor = new AuthorizationHeaderInterceptor(access_token);// 将拦截器添加到RestTemplaterestTemplate.getInterceptors().add(interceptor);}public Object getReqRes(String path){ServiceInstance services= discoveryClient.getInstances("consumer-service").get(0);String host = services.getHost();int port = services.getPort();StringBuffer reqUrl = new StringBuffer();reqUrl.append("http://");reqUrl.append(host);reqUrl.append(":"+port);Object res = restTemplate.getForObject(reqUrl.toString()+path,Object.class);return res;}}