在Spring Boot中,@RestController有效但@Controller无效

3

你好,我使用Spring Initializr创建了一个简单的Spring Boot应用程序。

我在与主应用程序类相同的文件夹中添加了一个控制器。

package com.demo.CrudOperations;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


  @Controller
  public class RegistrationController {

      @RequestMapping(value = "/welcome", method= RequestMethod.GET )
      public String register(){
        return "registration";
    }

  }

以下是您需要翻译的内容:

访问http://localhost:8080/welcome时出现以下错误:

白标签错误页面 该应用程序没有显式映射/error,因此您将其视为后备。

2020年12月19日星期六IST 12:51:44 发生了意外错误(类型=未找到,状态=404)。

如果我使用@restcontroller而不是@Controller,则会返回“registration”。 在我的WEB-INF下的视图中,我已创建registration.jsp。这是application.properties文件:

 spring.mvc.view.prefix=/WEB-INF/views
 spring.mvc.view.suffix=.jsp

pom.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.5.0-SNAPSHOT</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.CrudOperations</groupId>
    <artifactId>CrudOperations</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>CrudOperations</name>
    <description>Demo project for Crud Operations</description>

    <properties>
        <java.version>1.8</java.version>
    </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-jersey</artifactId>
        </dependency>
        
        <!-- JSTL for JSP -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>

以下是目录结构的样子

enter image description here

请问我哪里出错了?

我还尝试了添加@ResponseBody,但它给了我简单的字符串而不是JSP文件。


1
注意:如果你对Spring的调试不够熟悉,就不应该去折腾预发布版本。 (你的问题几乎肯定与JSP路径有关。 JSP是一个头疼的问题,这也是为什么Thymeleaf是新项目的更好选择之一的原因之一。) - chrylis -cautiouslyoptimistic-
@chrylis-cautiouslyoptimistic- 这可能是一个错误吗?为什么JSP会表现出这样的行为?我自己也在与同样的问题苦苦挣扎。这是我的帖子链接:https://stackoverflow.com/questions/65366871/could-jsp-file-not-found-be-a-bug-in-spring/65369026#65369026 - Gabriel Rogath
JSP是一种遗留技术,webapp/WEB-INF有一些奇怪的规则很难搞清楚。使用其他模板引擎,模板只是数据文件,适用普通规则。 - chrylis -cautiouslyoptimistic-
JSP只能与war文件一起使用,因为需要加载资源。请参阅(其中之一)https://github.com/spring-projects/spring-boot/issues/23829,并阅读[文档](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-jsp-limitations)。 - M. Deinum
4个回答

0
遇到这个问题,花了一些时间学习,所以我找到了这个...
使用注解@Controller的控制器默认返回视图(HTML模板),通常与ThymeleafJSP或其他模板引擎结合使用。 @RestController用于构建返回JSONXML等格式数据的Web服务。
为了使用@Controller,你可以这样做 ->
@GetMapping下方添加@ResponseBody注解 ->
@Controller
public class MyController {

    @GetMapping("/message")
    @ResponseBody
    public String showMessage() {
        return "Hello, this is a simple message!";
    }
}

或者你可以:
@GetMapping("/message2")
public ResponseEntity<String> getEmployeeById(){
    return new ResponseEntity<String>("Your response...", HttpStatus.OK);
}

肯定有更多的选择来避免白标错误页面,只需要找到方法...

0
在属性末尾添加"/"。

spring.mvc.view.prefix=/WEB-INF/views/


0

我曾经遇到过同样的问题,尝试了很多方法但都无法解决。原来问题的根本在于,Thymeleaf 在 application.yaml 中被禁用了。

  server:
  port: 8091
  servlet:
    session:
      timeout: 600s

spring:
  thymeleaf:
    enabled: true
  datasource:
    name: dbname  #数据库名
    url: jdbc:mysql://localhost:3306/
    username: username  #用户名
    password: password  #密码
    driver-class-name: com.mysql.cj.jdbc.Driver  #数据库链接驱动
    type: com.alibaba.druid.pool.DruidDataSource #使用druid数据源
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  redis:
    port: 6379
    host: "localhost"

mybatis:
  type-aliases-package: matsk.mszdqabbs.Pojo
  mapperLocations: classpath:mapper/*.xml
  configuration:
    use-generated-keys: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

logging:
  pattern:
    file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
  file:
    max-history: 30
    max-size: 10MB
    path: "./logs"
    name: "./logs/mszdqabbs.log"
  level:
    root: INFO


-1
这个依赖意味着你在你的Spring Boot应用程序中内部使用了Spring MVC。
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

所以你需要在这里使用一个ModelAndView对象,该对象必须由你的方法返回。

ModelAndView是Web MVC框架中Model和View的容器。请注意,它们是完全不同的。这个类仅仅将它们都保存在一起,使得控制器能够以单个返回值返回模型和视图。它表示了处理程序返回的模型和视图,由DispatcherServlet来解析。视图可以是一个字符串视图名称,需要通过ViewResolver对象来解析;也可以直接指定一个View对象。模型是一个Map,允许使用多个以名称为键的对象。

关于ModelAndView的更多细节,请参考这里
试一试吧

@RequestMapping(value = "/welcome", method= RequestMethod.GET )
  public ModelAndView register(){

    return new ModelAndView("registration");
}

依赖已经存在,你不必返回ModelAndView,还有其他多种选择。 - M. Deinum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接