当前位置: 首页 > 知识库问答 >
问题:

SpringBootDocker容器返回一个文件而不是jsp视图

屠盛
2023-03-14

我有一个简单的docker化Spring靴应用程序。当我在本地运行应用程序(没有docker)一切运行正常。控件返回jsp视图。

但当我使用容器运行应用程序时,它会返回一个包含html代码的文件。我可以尝试强制控制器返回html响应而不是八位字节流,但这不是一个聪明的解决方案

我意识到问题在jasper、tomcat和docker通信之间,但我找不到它,于是我尝试了一系列解决方案。

任何帮助都很感激,

这是我的配置

谢谢

项目结构

├── main/
│   ├── java/
│   │   └── com/
│   │       └── example/
│   │           └── jsp/
│   │               ├── configuration/
│   │               │   └── MvcConfiguration.java
│   │               ├── controller/
│   │               │   ├── IndexController.java
│   │               │   └── ProductController.java
│   │               ├── JspApplication.java
│   │               ├── model/
│   │               │   ├── Author.java
│   │               │   ├── ProductCategory.java
│   │               │   └── Product.java*
│   │               ├── service/
│   │               │   ├── ProductServiceImpl.java
│   │               │   └── ProductService.java*
│   │               └── test/
│   │                   └── CustomClass.java
│   └── resources/
│       ├── application.properties
│       └── META-INF/
│           └── resources/
│               └── index.jsp
└── test/
    └── java/
        └── com/
            └── example/
                └── jsp/
                    └── JspApplicationTests.java


application.properties

spring.mvc.view.suffix=.jsp

logging.level.org.springframework=DEBUG
logging.level.com=DEBUG

server.port=8080
spring.rabbitmq.host=

MVC配置。JAVA

package com.example.jsp.configuration;

import com.example.rabbit.client.pageview.PageViewService;
import com.example.rabbit.client.pageview.PageViewServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {

    @Bean
    public PageViewService pageViewService(RabbitTemplate template) {
        return new PageViewServiceImpl(template);
    }
}

波姆。xml

<?xml 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>jsp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>jsp</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <docker.image.prefix>eps</docker.image.prefix>
        <docker.image.name>pageview_controller</docker.image.name>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.3.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>required</scope>
        </dependency>

        <dependency>
            <groupId>com.example.rabbit</groupId>
            <artifactId>client</artifactId>
            <version>1.5-SNAPSHOT</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.20.0</version>

                <configuration>
                    <dockerHost>unix:///var/run/docker.sock</dockerHost>

                    <verbose>true</verbose>
                    <images>
                        <image>
                            <name>${docker.image.prefix}/${docker.image.name}</name>
                            <build>
                                <dockerFileDir>${project.basedir}/target/dockerfile</dockerFileDir>

                                <!--copies artficact to docker build dir in target-->
                                <assembly>
                                    <descriptorRef>artifact</descriptorRef>
                                </assembly>
                                <tags>
                                    <tag>latest</tag>
                                    <tag>${project.version}</tag>
                                </tags>
                            </build>
                            <run>
                                <ports>
                                    <port>8080:8080</port>
                                </ports>
                            </run>
                        </image>
                    </images>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.5.0</version>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.example.jsp.test.CustomClass</mainClass>
                    <arguments>${project.name},${project.version}</arguments>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

IndexController.java

package com.example.jsp.controller;

import com.example.jsp.service.ProductService;
import com.example.rabbit.client.pageview.PageViewService;
import guru.springframework.model.events.PageViewEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;
import java.util.UUID;

@Controller
public class IndexController {

    private static final Logger log = LoggerFactory.getLogger(IndexController.class);

    private ProductService productService;
    private PageViewService pageViewService;;

    @Autowired
    public IndexController(ProductService productService,
                            PageViewService pageViewService
    ) {

        this.productService = productService;
        this.pageViewService = pageViewService;

    }

    @GetMapping({"/", "index"})
    public ModelAndView getIndex(ModelAndView model){

        model.addObject("products", productService.listProducts());

        //Send Page view event
        PageViewEvent pageViewEvent = new PageViewEvent();
        pageViewEvent.setPageUrl("/");
        pageViewEvent.setPageViewDate(new Date());
        pageViewEvent.setCorrelationId(UUID.randomUUID().toString());

        log.info("Sending Message to pagie view service");
        pageViewService.sendPageViewEvent(pageViewEvent);

        model.setViewName("index");
        return model;
    }

}

我正在使用fabric8自动构建我的图像。在构建阶段,CustomClass将基于以下模板创建Dockerfile。

FROM openjdk
VOLUME /tmp
ADD maven/${fileName}.jar ${fileName}.jar
RUN sh -c 'touch /${fileName}.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/${fileName}.jar"]

CustomClass只是一个哑文件阅读器/编写器类,它基于pomx.ml变量动态创建Dockerfile

定制类

public class CustomClass {
    public static void main(String[] args) throws IOException {

        String projectName = args[0];
        String version = args[1];

        File file = new File("development/DockerfileTemplate");
        FileReader reader = new FileReader(file.getAbsoluteFile());

        StringBuilder sb = new StringBuilder();

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line+"\n");
            }
        } catch (Exception e) {

        }

        String content = sb.toString().replaceAll("\\$\\{fileName\\}", projectName+ "-" + version);

        File saveFile = new File("target/dockerfile/Dockerfile");
        saveFile.getParentFile().mkdirs();

        FileWriter fw = new FileWriter(saveFile);
        fw.write(content);
        fw.close();
    }
}

我注意到日志中有一个差异,不知道这是否相关

使用docker时,应用程序正在重定向并使用文件进行响应

2020-09-20 04:47:10.392 DEBUG 1 --- [nio-8080-exec-2] o.s.web.servlet.view.JstlView            : Forwarding to [index.jsp]
2020-09-20 04:47:10.392 DEBUG 1 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : "FORWARD" dispatch for GET "/index.jsp", parameters={}
2020-09-20 04:47:10.395 DEBUG 1 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2020-09-20 04:47:10.396 DEBUG 1 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Exiting from "FORWARD" dispatch, status 304
2020-09-20 04:47:10.396 DEBUG 1 --- [nio-8080-exec-2] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-09-20 04:47:10.396 DEBUG 1 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed 304 NOT_MODIFIED

在本地运行应用程序时,没有重定向

2020-09-20 07:47:54.461 DEBUG 1883 --- [nio-8080-exec-2] o.s.web.servlet.view.JstlView            : Forwarding to [index.jsp]
2020-09-20 07:47:54.461 DEBUG 1883 --- [nio-8080-exec-2] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2020-09-20 07:47:54.461 DEBUG 1883 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed 200 OK

共有2个答案

芮学
2023-03-14

在IndexController.java试试这个

@GetMapping({"/", "index"})
public ModelAndView getIndex(ModelAndView model){

    model.addObject("products", productService.listProducts());

    //Send Page view event
    PageViewEvent pageViewEvent = new PageViewEvent();
    pageViewEvent.setPageUrl("/");
    pageViewEvent.setPageViewDate(new Date());
    pageViewEvent.setCorrelationId(UUID.randomUUID().toString());

    log.info("Sending Message to pagie view service");
    pageViewService.sendPageViewEvent(pageViewEvent);

    return new ModelAndView("index", model);
}
仲孙鸿飞
2023-03-14

因此,在docker中部署服务JSP时有一些限制。下面是一些有趣的信息,这些信息帮助我找到了解决方案,为什么Spring boot不支持jsp,而如果我们添加适当的jar引用,它可以呈现页面

这是解决办法。它使用apache提供页面服务

Dockerfile模板

From tomcat
RUN rm -rf /usr/local/tomcat/webapps/*
COPY maven/${fileName}.war /usr/local/tomcat/webapps/ROOT.war

项目结构

├── main/
│   ├── java/
│   │   └── com/
│   │       └── example/
│   │           └── jsp/
│   │               ├── configuration/
│   │               │   └── BeanConfiguration.java
│   │               ├── controller/
│   │               │   └── IndexController.java
│   │               ├── converter/
│   │               │   ├── ProductFormToProduct.java*
│   │               │   └── ProductToProductForm.java*
│   │               ├── dto/
│   │               │   └── ProductForm.java
│   │               ├── JspApplication.java
│   │               ├── model/
│   │               │   └── Product.java
│   │               ├── repository/
│   │               │   └── ProductRepository.java
│   │               ├── service/
│   │               │   └── ProductService.java
│   │               ├── test/
│   │               │   └── CustomClass.java
│   │               └── utility/
│   │                   └── HtmlFormatter.java
│   ├── resources/
│   │   ├── application.properties
│   │   └── META-INF/
│   └── webapp/
│       ├── assets/
│       │   ├── css/
│       │   │   └── main.css
│       │   └── js/
│       │       └── script.js
│       └── WEB-INF/
│           └── view/
│               ├── fragments/
│               │   └── nav.jsp
│               └── product/
│                   ├── list.jsp
│                   ├── productform.jsp
│                   └── show.jsp
└── test/
    └── java/
        └── com/
            └── example/
                └── jsp/
                    └── JspApplicationTests.java

主Spring Boot应用程序类

package com.example.jsp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class JspApplication extends SpringBootServletInitializer {

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


    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(JspApplication.class);
    }
}

波姆。xml

<?xml 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>jsp</artifactId>
    <version>0.0.2-SNAPSHOT</version>
    <name>jsp</name>
    <description>Demo project for Spring Boot</description>
    <packaging>war</packaging>

    <properties>
        <project.name>jsp</project.name>
        <java.version>1.8</java.version>
        <docker.image.prefix>test</docker.image.prefix>
        <docker.image.name>dockertest</docker.image.name>
    </properties>

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--WEBJARS-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
            <version>0.40</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <repository>${docker.image.prefix}/${project.artifactId}</repository>
                    <buildArgs>
                        <WAR_FILE>target/${project.build.finalName}.war</WAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>

            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.20.0</version>

                <configuration>
                    <!--<dockerHost>http://127.0.0.1:2375</dockerHost>-->
                    <dockerHost>unix:///var/run/docker.sock</dockerHost>

                    <verbose>true</verbose>
                    <images>
                        <image>
                            <name>${docker.image.prefix}/${docker.image.name}</name>
                            <build>
                                <dockerFileDir>${project.basedir}/target/dockerfile</dockerFileDir>

                                <!--copies artficact to docker build dir in target-->
                                <assembly>
                                    <descriptorRef>artifact</descriptorRef>
                                </assembly>
                                <tags>
                                    <tag>latest</tag>
                                    <tag>${project.version}</tag>
                                </tags>
                            </build>
                            <run>
                                <ports>
                                    <port>8080:8080</port>
                                </ports>
                            </run>
                        </image>
                    </images>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.5.0</version>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.example.jsp.test.DockerFileBulder</mainClass>
                    <arguments>${project.name},${project.version}</arguments>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

DockerFileBulder

        String projectName = args[0];
        String version = args[1];

        File file = new File("development/DockerfileTemplate");
        FileReader reader = new FileReader(file.getAbsoluteFile());

        StringBuilder sb = new StringBuilder();

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line+"\n");
            }
        } catch (Exception e) {

        }

        String content = sb.toString().replaceAll("\\$\\{fileName\\}", projectName+ "-" + version);

        File saveFile = new File("target/dockerfile/Dockerfile");
        saveFile.getParentFile().mkdirs();

        FileWriter fw = new FileWriter(saveFile);
        fw.write(content);
        fw.close();
 类似资料:
  • 我试图理解整个Spring框架。据我所知,相对较新的使用gradle的技术使得很多教程和在线帖子过时了? 我遇到的主要问题是,当我尝试显示jsp或html页面时,网页正文显示文本:“filename.jsp”。 该项目由New-创建 文件夹结构: 测试 --Spring元件(由STS创建) --src/main/java-TEST-TestApplication。java(由STS创建)——测试。

  • 问题内容: 我有一个元素定义为 我想读取此元素中的文本,即“ ABC”,但这样做是:var client = page.clientRowName.getText(); 返回一个对象而不是一个字符串。还有什么其他方法可以获取元素的文本 问题答案: 返回一个promise,您需要 解决 它: 或者,如果您只想声明文本,请为您解决承诺: 承诺和“控制流”文档页面应清除所有内容。

  • 问题内容: 我将数据存储在HashMap中(键:字符串,值:ArrayList)。我遇到问题的部分声明了一个新的ArrayList“当前”,在HashMap中搜索字符串“ dictCode”,如果找到,则将current设置为返回值ArrayList。 “ current = …”行返回编译器错误: 我不明白… HashMap是否返回一个Object而不是我存储在其中的ArrayList作为值?如

  • 本文向大家介绍Ajax中responseText返回的是一个页面而不是一个值,包括了Ajax中responseText返回的是一个页面而不是一个值的使用技巧和注意事项,需要的朋友参考一下 自己在struts2中的写好了业务逻辑用response返回的内容却是一个页面的! 然后就去了百度一下,说的是将struts2的返回值设为null(return null),这是因为struts2返回的是一个页面

  • 我正在查询URI以从web服务获取一些数据。那很好。但我注意到,我的json hase多页的page\u计数,但只返回第一页数据。 以下是json的样子: 如何返回所有页面而不是只返回第一页?我知道这可能不是个好主意,但我该怎么做? 更新:web服务的URI类似于: 谢谢

  • 我正在为二和leetcode问题实现一个哈希映射。 映射的第一个数组创建一个散列数组作为“索引”,它是nums数组中每个元素的目标差异。然后,我对映射数组应用一个过滤器,以查看映射数组的2个元素是否包含在nums数组中,并返回这些元素的索引。 当索引被过滤到returnedArr中时,它似乎返回nums的第一个元素,而不是两个索引。[2] 返回之前的日志记录显示它正确地分别注册了索引0和1,而不是