从 docker 容器执行时,SpringBoot RestTemplate 返回 403 禁止
Posted
技术标签:
【中文标题】从 docker 容器执行时,SpringBoot RestTemplate 返回 403 禁止【英文标题】:SpringBoot RestTemplate return 403 forbidden when executing from docker container 【发布时间】:2020-11-14 23:09:33 【问题描述】:我正在尝试使用 Java 代码实现 Spring Boot RestTemplate 并调用外部 REST 服务。这是作为 java 应用程序工作,但是当我 在 docker 容器中部署相同的代码时出现错误
org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: [error code: 1010]
这是我的代码..独立运行..
@RequestMapping(value = "/extservice",
produces = MediaType.APPLICATION_JSON_VALUE,
method = RequestMethod.GET)
public User httpcall()
ResponseEntity<User> result = null;
try
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Object> entity = new HttpEntity<Object>(headers);
final String uri = "https://reqres.in/api/users/2";
RestTemplate restTemplate = new RestTemplate();
result = restTemplate.getForEntity(uri, User.class);
System.out.println(result.toString());
catch (Exception e)
e.printStackTrace();
return result.getBody();
这是错误堆栈跟踪
org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: [error code: 1010]
at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:109)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:170)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:112)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:782)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:740)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:342)
at com.dockerforjavadevelopers.hello.HelloController.httpcall(HelloController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
....
2020-07-25 04:52:17.578 ERROR 1 --- [nio-9898-exec-4] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/opa-test] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at com.dockerforjavadevelopers.hello.HelloController.httpcall(HelloController.java:48) ~[classes!/:0.1.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_212]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_212]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_212]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_212]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.6.RELEASE.jar!/:5.2.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.6.RELEASE.jar!/:5.2.6.RELEASE]
这是我的 docker 文件
# Maven build container
FROM maven:3.6.3-jdk-11-slim as mavenbuild
COPY pom.xml /tmp/
COPY src /tmp/src/
WORKDIR /tmp/
RUN mvn package
#pull base image
FROM openjdk:8-jdk-alpine
EXPOSE 9898
#default command
CMD java -jar /data/opa-test-0.1.0.jar
#copy hello world to docker image from builder image
COPY --from=mavenbuild /tmp/target/opa-test-0.1.0.jar /data/opa-test-0.1.0.jar
【问题讨论】:
你能显示docker文件吗 添加有问题..供参考..我可以从同一个微服务访问 ping 方法..它正在返回响应.. 你能卷曲你试图通过RestTemplate
调用的endpoint
吗?
另外,请在您使用 HTTPS
时查看此内容,it 可能会有所帮助。
我正在尝试这样做..但令人惊讶的是,它在作为应用程序运行 [不在容器中] 但在 docker 容器中失败时工作正常
【参考方案1】:
您已创建 HttpHeaders 对象但未使用。 请使用 RestTemplate 的交换方式。
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Application");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> responseJson = restTemplate.exchange(resourceUrl, HttpMethod.GET, entity, String.class);
【讨论】:
以上是关于从 docker 容器执行时,SpringBoot RestTemplate 返回 403 禁止的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot @RestController 无法从 docker 容器外部访问
如何从不同的 docker 容器中读取 Spring Boot 应用程序属性?
无法从 docker 容器内的 Spring Boot 连接到 Redis
『中级篇』docker之java容器运行外置springboot-jar(番外篇)(79)