英文:
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 "java" command line in a docker container then, it doesn'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("/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;
}
}
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 "/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"]
答案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 = "/";
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 Remplacer par un ServiceException
throw new Exception();
}
return absolutePathString;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论