简体   繁体   English

Dockerized SpringBoot REST api 不支持请求方法“GET”

[英]Request method 'GET' not supported in Dockerized SpringBoot REST api

I have a small spring application as shown below:我有一个小的弹簧应用程序,如下所示:

package com.example.demo.api;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("api/factorial")
@RestController
public class TestApi {

    @GetMapping
    public long factorial(){
        long startTime = System.nanoTime();
        int i;
        double fact=1;
        int number=50;//It is the number to calculate factorial
        for(i=1;i<=number;i++){
            fact=fact*i;
            System.out.println("Factorial of "+i+" is: "+fact);
        }
        long endTime = System.nanoTime();
        return (endTime - startTime);
    }
}

I have generated a jar of this application and dockerized it as shown below:我已经生成了这个应用程序的一个 jar 并将其 dockerized 如下所示:

FROM openjdk:8-jdk-alpine
ADD  ./demo-0.0.1-SNAPSHOT.jar /usr/src/factorial/
WORKDIR /usr/src/factorial
EXPOSE 8080
CMD java -XX:+PrintFlagsFinal $JAVA_OPTIONS -jar demo-0.0.1-SNAPSHOT.jar

I then run the below command run the docker container然后我运行下面的命令运行 docker 容器

docker run --rm --name factorialContainer -p 8080:8080 -e JAVA_OPTIONS="$(cat jvmFlags.txt)" suleka96/factorial:latest

Then I am trying to make a HTTP request to the REST endpoint using JMeter as shown below然后我尝试使用 JMeter 向 REST 端点发出 HTTP 请求,如下所示在此处输入图片说明

The problem is that when i do this I get an error saying:问题是,当我这样做时,我收到一条错误消息:

org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported org.springframework.web.HttpRequestMethodNotSupportedException:不支持请求方法“GET”

However, when I run the spring application locally (without dockerizing it) and send a request from JMeter, the request successfully gets sent.但是,当我在本地运行 spring 应用程序(不对其进行 dockerizing)并从 JMeter 发送请求时,请求成功发送。

What am I doing wrong?我究竟做错了什么?

Your application is deployed in docker, so it is virtual machine.您的应用程序部署在 docker 中,因此它是虚拟机。 That is another host with it's own ip address.那是另一台拥有自己IP地址的主机。 But you are trying to send GET request to localhost.但是您正在尝试向本地主机发送 GET 请求。 You should get your docker ip.你应该得到你的 docker ip。 Type this to get ip in Mac OS在 Mac OS 中键入此内容以获取 ip

host> docker-machine ip default主机> docker-machine ip 默认

Visit that page https://spring.io/guides/gs/spring-boot-docker/ there's a section about mac os deployment in that knowledge base访问该页面https://spring.io/guides/gs/spring-boot-docker/在该知识库中有一个关于 mac os 部署的部分

The reason behind this has got to be in the logs.这背后的原因必须在日志中。

Here's my setup, I changed the controller so it would return json rather than the long primitive:这是我的设置,我更改了控制器,因此它会返回 json 而不是 long 原语:

Controller控制器

@RequestMapping("api/factorial")
@RestController
public class TestApi {

    @GetMapping
    public Map<String, Long> factorial(){
        long startTime = System.nanoTime();
        int i;
        double fact=1;
        int number=50;//It is the number to calculate factorial
        for(i=1;i<=number;i++){
            fact=fact*i;
            System.out.println("Factorial of "+i+" is: "+fact);
        }
        long endTime = System.nanoTime();
        Map<String, Long> res = new HashMap<String, Long>();
        res.put("time_in_nanos", (endTime - startTime));
        return res;
    }
}

Application应用

@SpringBootApplication(scanBasePackages = "com.example.demo")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

pom绒球

ml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <properties>
        <springboot.version>2.0.8.RELEASE</springboot.version>
    </properties>

    <dependencies>
    <!-- Springboot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <version>${springboot.version}</version>
        <scope>compile</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
        <version>${springboot.version}</version>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${springboot.version}</version>
        <optional>true</optional>
    </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${springboot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>build-info</goal>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

Docker command line Docker 命令行

docker run --rm --name apiTest -p 8080:8080  321225ee07bb

I used your Dockerfile pretty much as is我几乎按原样使用了你的 Dockerfile

Log out put from the container:从容器中注销:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.8.RELEASE)

2020-02-04 22:55:03.774  INFO 1 --- [           main] com.example.demo.api.Application         : Starting Application on 33f1f71d079b with PID 1 (/usr/src/factorial/demo-1.0.jar started by root in /usr/src/factorial)
2020-02-04 22:55:03.796  INFO 1 --- [           main] com.example.demo.api.Application         : No active profile set, falling back to default profiles: default
2020-02-04 22:55:04.076  INFO 1 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2f410acf: startup date [Tue Feb 04 22:55:04 GMT 2020]; root of context hierarchy
2020-02-04 22:55:08.891  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-02-04 22:55:09.002  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-02-04 22:55:09.004  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.37
2020-02-04 22:55:09.055  INFO 1 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2020-02-04 22:55:09.305  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-02-04 22:55:09.307  INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 5236 ms
2020-02-04 22:55:10.617  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2020-02-04 22:55:10.626  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webMvcMetricsFilter' to: [/*]
2020-02-04 22:55:10.636  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2020-02-04 22:55:10.641  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2020-02-04 22:55:10.645  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2020-02-04 22:55:10.647  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpTraceFilter' to: [/*]
2020-02-04 22:55:10.649  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
2020-02-04 22:55:11.290  INFO 1 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-02-04 22:55:11.658  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2f410acf: startup date [Tue Feb 04 22:55:04 GMT 2020]; root of context hierarchy
2020-02-04 22:55:11.864  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/factorial],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Long> com.example.demo.api.TestApi.factorial()
2020-02-04 22:55:11.879  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2020-02-04 22:55:11.880  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2020-02-04 22:55:11.960  INFO 1 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-02-04 22:55:11.962  INFO 1 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-02-04 22:55:12.745  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2020-02-04 22:55:12.787  INFO 1 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2020-02-04 22:55:12.792  INFO 1 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2020-02-04 22:55:12.796  INFO 1 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto protected java.util.Map<java.lang.String, java.util.Map<java.lang.String, org.springframework.boot.actuate.endpoint.web.Link>> org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.links(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2020-02-04 22:55:12.950  INFO 1 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2020-02-04 22:55:13.124  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-02-04 22:55:13.135  INFO 1 --- [           main] com.example.demo.api.Application         : Started Application in 10.73 seconds (JVM running for 12.233)

What I'd look for is the mapping of the GET request like this:我要寻找的是这样的 GET 请求的映射:

2020-02-04 22:55:11.864  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/factorial],methods=[GET]}" onto public java.util.Map<java.lang.String, java.lang.Long> com.example.demo.api.TestApi.factorial()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM