【问题标题】:JSPs with Spring Boot使用 Spring Boot 的 JSP
【发布时间】:2021-08-10 09:57:08
【问题描述】:

我一直在做一个用 spring initialzr 初始化的 spring-boot 项目。生成的包没有/webapp目录,因此必须添加/webapp目录。我从 spring 文档中读到 spring 检测来自/staticresources 的静态文件。我放置了 3 个不同的 index.jsp 来测试我的控制器显示哪个。下面是代码sn-ps。

目录树:

├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── databasedisplay
│   │   │           └── app
│   │   │               ├── AppApplication.java
│   │   │               ├── config
│   │   │               │   ├── WebAppInitializer.java
│   │   │               │   └── WebConfig.java
│   │   │               ├── controller
│   │   │               │   ├── HomeController.java
│   │   │               │   └── IndexController.java
│   │   │               ├── repository
│   │   │               └── ServletInitializer.java
│   │   ├── resources
│   │   │   ├── application.properties
│   │   │   ├── index.jsp
│   │   │   ├── static
│   │   │   │   └── index.jsp
│   │   │   └── templates
│   │   └── webapp
│   │       └── WEB-INF
│   │           └── views
│   │               └── index.jsp
│   └── test
│       └── java
│           └── com
│               └── databasedisplay
│                   └── app
│                       └── AppApplicationTests.java
└── target
    ├── classes
    │   ├── application.properties
    │   ├── com
    │   │   └── databasedisplay
    │   │       └── app
    │   │           ├── AppApplication.class
    │   │           ├── config
    │   │           │   ├── WebAppInitializer.class
    │   │           │   └── WebConfig.class
    │   │           ├── controller
    │   │           │   ├── HomeController.class
    │   │           │   └── IndexController.class
    │   │           └── ServletInitializer.class
    │   ├── index.jsp
    │   └── static
    │       └── index.jsp
    ├── generated-sources
    │   └── annotations
    ├── generated-test-sources
    │   └── test-annotations
    ├── maven-status
    │   └── maven-compiler-plugin
    │       ├── compile
    │       │   └── default-compile
    │       │       ├── createdFiles.lst
    │       │       └── inputFiles.lst
    │       └── testCompile
    │           └── default-testCompile
    │               ├── createdFiles.lst
    │               └── inputFiles.lst
    └── test-classes
        └── com
            └── databasedisplay
                └── app
                    └── AppApplicationTests.class

index.jsp(在“/resources”中)

<html>
<head></head>
<body>
    <h1>This is the body of the sample view in /resources</h1>
</body>

index.jsp(在“/static”中)

<html>
    <head></head>
    <body>
        <h1>This is the body of the sample view in /static</h1>
    </body>
</html>

index.jsp(在'/WEB-INF/views/'中)

<html>
    <head></head>
    <body>
        <h1>This is the body of the sample view in WEB-INF/views</h1>
    </body>
</html>

控制器

@Controller
public class IndexController {

    @RequestMapping(value = "/indexA", method = RequestMethod.GET)
    public String index() {
        return "index";
    }
}

配置类

WebConfig.java

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver
                = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable("testServlet");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/resources/").setCachePeriod(3600)
                .resourceChain(true).addResolver(new PathResourceResolver());
    }


}

WebInitializer.java

    public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();

        context.scan("com.databasedisplay.app");

        container.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic dispatcher = container.addServlet("mvc", new DispatcherServlet(context));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

}

问题是当我使用mvn spring-boot:runmvn clean package spring-boot:run 运行时,目录树中显示的\target 目录没有来自\WEB-INF\views\index.jsp(实际上目标目录没有@987654338 @ 目录)。但是当我 curl http://localhost:8080/indexA 时,我仍然得到以下输出: This is the body of the sample view in WEB-INF/views

  1. 有人可以解释视图解析器如何将视图名称映射到相应的视图吗? (我已经研究了InternalResourceViewResolver 以及如何设置前缀和后缀,但这仍然不能解释它如何在 jsp 不在目标中时呈现它)

  2. 有人能指出mvn spring-boot:runmvn clean package spring-boot:run 之间的区别吗,因为后者在目标中有WEB-INF 目录。

  3. 为什么我得到的index.jsp 对应于/WEB-INF 而不是curl 上的其他视图?

【问题讨论】:

  • 为什么要使用 JSP 而不是 .HTML 和 JavaScript 模板?这就是 src/main/resources/static 目录的用途。根据一些文档:“尽管传统应用程序的 Boot 仍然支持 Java 服务器页面 (JSP) 等长期建立的标准,但大多数当前应用程序要么利用仍在不断发展和维护的模板引擎支持的更强大的视图技术,要么转移前端开发到 HTML 和 JavaScript 的组合。甚至可以成功地混合这两个选项并发挥各自的优势。"
  • 好点@kenneth,将按照建议进行更改,但仍然对应用程序的行为感到好奇。

标签: spring-boot maven jsp


【解决方案1】:

JSP 是遗留 Java 企业应用程序的一部分,不是 Spring Boot/MVC 的核心,它是更现代的模板引擎方法(尽管 Spring 基于 Java EE)。如果您有充分的理由使用 JSP,它可以工作。但是对于 Spring,MVC 方法/实现是使用更现代的模板引擎和技术,如 ThymeleafFreeMarkerGroovy Markup 和 小胡子。

问题 1 如果您正确配置了 pom.xml,则可以使用不同的启动器来配置应用程序的部署/运行方式。 JSP 不是 Spring 的标准解决方案,应该单独配置,需要对其进行配置,以便它将 JSP 编译到它们各自的位置,以便 Tomcat 从webapps 文件夹中读取它。要编译和渲染 JSP,你的 pom.xml 需要 spring-boot-starter-webtomcat-embed-jasper,包括标签 &lt;scope&gt;provided&lt;/scope&gt;

问题 2Spring 带有一个嵌入式 Tomcat 服务器 (spring-boot-starter-web)。当您运行 mvn spring-boot:run 时,它将启动一个 Tomcat 服务器并在 Tomcat localhost:8080 上部署您的 Spring Boot 应用程序。 mvn clean,在spring-boot:run之前,只是通过删除构建目录来删除构建的输出。

问题 3 在编译之前,每个 .HTML 模板或 .JSP 文件在项目中都有各自的位置,因此某些 .JSP 没有编译到您的文件夹中。

Java Enterprise 应用程序及其对应的 JSP 使用与 Spring 不同的项目结构:如果您有正确的依赖项并运行 @987654329,所有 JSP 都将从“src/main/webapp/WEB-INF/jsp/”编译@。如果您手动创建项目,通过 cmd -jar 编译,您应该将您的 JSP 包含在 "/webapp/" 文件夹中,并将 Java.classes 包含在 WEB-INF/classes/ 中MyServlet.class.

例如通过使用 Thymeleaf (spring-boot-starter-thymeleaf),如果您构建工件,IDE 将从 /resources/templates 编译模板并在您的 MVC 项目上工作,您可以在其中无缝集成您的 REST 控制器.

Tomcat 在您的企业应用程序的部署方式中保持关键地位,只是您需要在 Spring 中调整您的项目,以便在部署之前将正确的文件映射并编译到 .WAR 中。

对于 MVC,我的建议是使用模板引擎而不是传统的 JSP。当然,在 Spring 项目中会有 JSP 的用例,但它需要不同的结构和依赖关系。

【讨论】:

  • 非常感谢@kenneth。如果有人发现它有用mvn package 命令如果使用 maven,则构建一个在 pom.xml 文件中定义的 jar/war,然后可以使用 jar 命令运行它。但是,一些 Spring Boot 开发工具可能不适用于这种方式。因此,我发现使用mvn spring-boot:run 运行会更好。
猜你喜欢
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 2018-01-13
  • 2014-06-11
  • 2017-04-04
  • 2019-11-21
  • 1970-01-01
相关资源
最近更新 更多