Spring Boot REST控制器在将包打成JAR文件后无法工作。

huangapple go评论74阅读模式
英文:

Spring Boot rest controller not working when package in a jar

问题

我正在使用Spring Boot的REST控制器开发一个REST API出现了一些奇怪的情况当我在Eclipse中测试控制器时一切正常但是当我将应用程序打包成一个jar包并在Docker容器中使用java命令行启动时它就无法工作
让我困惑的是没有日志当我在控制器开头处放置了一个**sysout**我意识到控制器甚至没有被执行

以下是带有相关端点的控制器但我不确定它是否有帮助

```java
@RestController
@RequestMapping("/pdf")
@EnableSwagger2
public class PDFGeneratorResources {
    @Autowired
    PDFGenerator pdfService;

    @Autowired
    ResourceLoader resourceLoader;

    @PostMapping("/generate-recipies-shoppinglist")
    public ResponseEntity<String> generateRecipiesAndShoppingListPDF(@RequestBody List<Day> daysList) {
        System.out.println("TRACE");
        ResponseEntity<String> responseEntity = null;
        String generatedPDFFileURL = "";

        try {
            generatedPDFFileURL = pdfService.generatePDFFromHTML(PDFTemplates.RecipiesAndShoppingList,
                new RecipiesShoppinglistContextBuilder(new ArrayList<Day>(daysList)));

            responseEntity = new ResponseEntity<String>(generatedPDFFileURL, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            responseEntity = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }

        return responseEntity;
    }
}

问题:是否有办法使Spring Boot记录从Tomcat到我的控制器之间发生的所有事情?类似Spring Boot的--verbose选项吗?

附注:
以下是我用于部署应用程序的DockerFile

FROM registry.gitlab.com/softreaver/meals-ready-backend/runners:centos7jdk11

MAINTAINER MILAZZO_christopher

COPY ./target/*.jar /app.jar
RUN echo -e "/usr/bin/java -Xms128m -Xmx128m -jar /app.jar\n" > /start-app.sh
RUN chmod u+x /start-app.sh

EXPOSE 8080

ENTRYPOINT ["/bin/bash", "/start-app.sh"]

<details>
<summary>英文:</summary>

I am developing a REST API using Spring Boot rest controller. Something strange is happening ; When I test my controller with Eclipse it is working just fine BUT when i deploy the app, packaged in a jar and started with the &quot;java&quot; command line in a docker container then, it doesn&#39;t work.
What confuse me is that there is no log. And when I put a **sysout** at the very beginning of my controller I realized that the controller is not even executed ! 

Here is the controller with the concerned endpoint, but i am not sure it will help :

```java
@RestController
@RequestMapping(&quot;/pdf&quot;)
@EnableSwagger2
public class PDFGeneratorResources {
    @Autowired
    PDFGenerator pdfService;

    @Autowired
    ResourceLoader resourceLoader;

    @PostMapping(&quot;/generate-recipies-shoppinglist&quot;)
    public ResponseEntity&lt;String&gt; generateRecipiesAndShoppingListPDF(@RequestBody List&lt;Day&gt; daysList) {
	System.out.println(&quot;TRACE&quot;);
	ResponseEntity&lt;String&gt; responseEntity = null;
	String generatedPDFFileURL = &quot;&quot;;

	try {
	    generatedPDFFileURL = pdfService.generatePDFFromHTML(PDFTemplates.RecipiesAndShoppingList,
		    new RecipiesShoppinglistContextBuilder(new ArrayList&lt;Day&gt;(daysList)));

	    responseEntity = new ResponseEntity&lt;String&gt;(generatedPDFFileURL, HttpStatus.OK);
	} catch (Exception e) {
	    e.printStackTrace();
	    responseEntity = new ResponseEntity&lt;&gt;(HttpStatus.INTERNAL_SERVER_ERROR);
	}

	return responseEntity;
    }
}

Question : Is there any way of making spring boot log everything that's happening between tomcat and my controller ? King of --verbose option for spring boot ?

PS:
Here is the DockerFile I am using to deploy the app

FROM registry.gitlab.com/softreaver/meals-ready-backend/runners:centos7jdk11

MAINTAINER MILAZZO_christopher

COPY ./target/*.jar /app.jar
RUN echo -e &quot;/usr/bin/java -Xms128m -Xmx128m -jar /app.jar\n&quot; &gt; /start-app.sh
RUN chmod u+x /start-app.sh


EXPOSE 8080

ENTRYPOINT [&quot;/bin/bash&quot;, &quot;/start-app.sh&quot;]

答案1

得分: 1

我终于通过 log.level.root=debug 找到了问题;我正在使用Spring资源加载器(resourceloader)来加载我的PDF服务模板,但它似乎无法在JAR文件内找到资源文件夹。

它显示:由于它不在文件系统中,所以无法解析为绝对文件路径:jar:file:/app.jar!/BOOT-INF/classes!/templates/......

英文:

I finally found the problem thx to log.level.root=debug ; I am using the Spring resourceloader to load the template for my PDF service but it seems that it is not able to find the resources folder inside a jar file.

It says : cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/templates/......

答案2

得分: 0

我在互联网上找到了一个解决方案,并通过使用inputStream使其正常工作:

@Service
public class ResourceLoaderService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    ResourceLoader resourceLoader;

    public String getResourceAbsolutePathString(String location) throws Exception {
        Resource resource = resourceLoader.getResource(location);

        String absolutePathString = "/";

        try {
            if (resource.getURL().getProtocol().equals("jar")) {
                logger.debug("Jar file system activated");

                File tempFile = Files.createTempFile("Mealsready_backend_", null).toFile();
                resource.getInputStream().transferTo(new FileOutputStream(tempFile));

                absolutePathString = tempFile.getAbsolutePath();
            } else {
                absolutePathString = resource.getFile().getAbsolutePath();
            }
        } catch (IOException e) {
            logger.error("Error while trying to retrieve a resource: " + e.getMessage());
            // TO DELETE Replace with a ServiceException
            throw new Exception();
        }

        return absolutePathString;
    }
}
英文:

I found a solution on internet and made it work by using inputStream :

@Service
public class ResourceLoaderService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    ResourceLoader resourceLoader;

    public String getResourceAbsolutePathString(String location) throws Exception {
	Resource resource = resourceLoader.getResource(location);

	String absolutePathString = &quot;/&quot;;

	try {
	    if (resource.getURL().getProtocol().equals(&quot;jar&quot;)) {
		logger.debug(&quot;Jar file system activated&quot;);

		File tempFile = Files.createTempFile(&quot;Mealsready_backend_&quot;, null).toFile();
		resource.getInputStream().transferTo(new FileOutputStream(tempFile));

		absolutePathString = tempFile.getAbsolutePath();
	    } else {
		absolutePathString = resource.getFile().getAbsolutePath();
	    }
	} catch (IOException e) {
	    logger.error(&quot;Error while trying to retrieve a resource : &quot; + e.getMessage());
	    // TO DELETE Remplacer par un ServiceException
	    throw new Exception();
	}

	return absolutePathString;
    }
}

huangapple
  • 本文由 发表于 2020年7月26日 05:53:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63093934.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定