繁体   English   中英

如何在 Spring 引导中从 RESTful controller 返回 HTML 页面?

[英]How to return an HTML page from a RESTful controller in Spring Boot?

我想从 controller 返回一个简单的 HTML 页面,但我只得到文件的名称而不是它的内容。 为什么?

这是我的 controller 代码:

@RestController
public class HomeController {

    @RequestMapping("/")
    public String welcome() {
        return "login";
    }
}

这是我的项目结构:

[在此处输入图像描述

像这样使用@RestController

@RestController
public class HomeController {

    @RequestMapping("/")
    public String welcome() {
        return "login";
    }
}

这与您在普通控制器中所做的相同:

@Controller
public class HomeController {

    @RequestMapping("/")
    @ResponseBody
    public String welcome() {
        return "login";
    }
}

使用@ResponseBody返回return "login"; 作为字符串对象。 您返回的任何对象都将作为payload作为 JSON 附加到 HTTP 正文中。

这就是为什么您只在响应中login的原因。

请按照以下步骤操作:

  1. 必须把html文件放在resources/templates/

  2. @Controller替换@RestController

  3. 如果您正在使用任何视图解析器,请删除。

  4. 您的控制器方法应返回没有扩展名的视图文件名,如return "index"

  5. 包括以下依赖项:

     <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>`

您可以尝试使用ModelAndView

@RequestMapping("/")
public ModelAndView index () {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("index");
    return modelAndView;
}

您应该使用login.html 并用Controller替换RestController

@Restcontroller替换@controller @Restcontroller只返回内容而不是 html 和 jsp 页面。

直到我将此依赖项添加到 pom 文件中后,Kukkuz 的答案才对我有用:

<!-- Spring boot Thymeleaf -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

这里的指南。

以及更新此处概述的注册表资源。

然后它开始工作得很好。 如果将来有人遇到相同的问题并且遵循第一个答案不能解决您的问题,请在使用@Kukkuz 答案中的代码后执行另外两个步骤,看看这是否有所不同。

我知道这很旧,但也许它可以帮助某人。 要在 RestController 中执行此操作,返回一个 String 是实际的 HTML 代码,然后浏览器将知道要显示什么。

我做了三件事:

  • 将 HTML 页面放在 {project.basedir}/resources/static/myPage.html;
  • 将@RestController 切换到@Controller;
  • 这是我的控制器:
@RequestMapping(method = RequestMethod.GET, value = "/")
public String aName() {
    return "myPage.html";
}

不需要特别的依赖

你只得到名字,因为你只return "login";名字return "login"; . 它是@RestController ,这个控制器返回数据而不是视图; 因此,您只能获得从方法返回的内容。

如果要显示此名称的视图,则需要使用 Spring MVC,请参阅此示例

@Controller替换@RestController

我没有使用 Thymeleaf,它对我有用的唯一方法是在课堂上使用@Controller

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

您在此处返回的String

 return "login";

实际上是您发送回浏览器的全部内容

如果您想将文件的内容发回,一种方法是:

  1. 打开文件
  2. 将内容读入字符串
  3. 返回值

您可以在问题 Spring boot service to download a file 上使用此答案

@Controller
public class HomeController {

    @RequestMapping(method = RequestMethod.GET, value = "/")
    public ModelAndView welcome() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("login.html");
        return modelAndView;
    }
}

这将返回 Login.html 文件。 Login.html 应该在静态文件夹内。

注意:没有添加thymeleaf依赖

@RestController
public class HomeController {

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

这将返回字符串登录

@kukkuz 几乎回答了“为什么?”这个问题。 对于那些仍在研究“如何”的人,积累其他人的回答。

使用 RestController:

@RestController
public class MyRestController {
    @RequestMapping("/")
    public ModelAndView welcome() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("login.html");
        return modelAndView;
    }  
}
  • 注意视图名称是:'login.html'(完整文件名)。
  • 文件所在的位置也很重要,默认情况下 login.html 必须在 resources/static 或 resources/public

您可以为默认后缀设置应用程序参数,例如:

 spring.mvc.view.suffix=.html

在这种情况下,视图名称必须没有像“登录”这样的扩展名。

可以使用一些建议的百里香叶。 意味着你的 pom.xml 依赖项是这样的:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
  <version>2.4.4</version>
</dependency>

在这种情况下,默认情况下 login.html 必须位于:resources/templates 文件夹中,并且调用类似,现在唯一的区别是视图名称,因为.html被 tymeleaf 用作默认值。

//  fails by default
//  NO fail if spring mvc view suffix is set in properties e.g.: spring.mvc.view.suffix=.html
//  NO fail if thymeleaf is added, and there is a file login.html in a resources/templates folder.
@RequestMapping("/loginTest")
public ModelAndView loginTest () {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("login");
    return modelAndView;
}

使用控制器:

@Controller
public class MyController {

  //gets html from a default 'resources/public' or 'resources/static' folder
  @RequestMapping(path="/welcome")
  public String getWelcomePage(){
      return "login.html";
  }

  //gets html from a default 'resources/public' or 'resources/static' folder
  @RequestMapping("/welcome1")
  public ModelAndView getWelcomePageAsModel() {
      ModelAndView modelAndView = new ModelAndView();
      modelAndView.setViewName("login.html");
      return modelAndView;
  }

  //  fails with 404 resource not found by default
  //  NO fail, if spring mvc view suffix is set in properties e.g.: spring.mvc.view.suffix=.html
  //  NO fail, if thymeleaf is added, and there is a file login.html in a resources/templates folder
  @RequestMapping(path="/welcome2")
  public String thisFails(){
      return "login";
  }
}

在用@RestController注释的类中用@GetMapping注释的方法可以通过两种方式返回视图(JSP、HTML 等)

@GetMapping("/dummy")
public String renderDummyWebPage() {
    return "dummy.jsp";
}

但是,这种方法有两个限制

  1. 该 JSP 页面必须存在于src/main/webapp目录中,否则如果视图存在于子目录中,则必须相应地修改返回类型。 例如,如果 JSP 页面存在于src/main/webapp/views目录中 - 它应该将views/dummy.jsp作为字符串返回。

  2. 如果您已经配置了应用程序的 ViewResolver,返回一个简单的 String 将不起作用,并且该 String 将被解释为一个普通的 String 而不是 JSP 视图名称。


为了克服这两个限制,您可以改为返回 ModelAndView。

@GetMapping("/dummy")
public ModelAndView renderDummyWebPage() {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("dummy");
    return modelAndView;
}

我希望这个答案会有所帮助,谢谢。

@kukkuz 和@Robby 已经用@RequestMapping 注释回答了,但我们也可以使用@GetMapping 注释。

@GetMapping("/index")
public ModelAndView welcome() {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("index.html");
    return modelAndView;
}

您可以在 RequestMapping 中指定 GET 或 POST 方法,如下所示:-

@RestController
public class HomeController {

@RequestMapping(value="/", Method="GET")  //or Method="POST"
public String welcome() {
    return "/login";
}
}

现在,如果您在此页面上请求,它将返回 login.html 页面

最正确和现代的形式是使用IoC将依赖项放入端点方法中,例如thymeleaf Model实例...

 @Controller 
 public class GreetingController {
        @GetMapping("/greeting") 
        public String greeting(
            @RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
             model.addAttribute("name", name); 
             return "greeting"; 
             // returns the already proccessed model from src/main/resources/templates/greeting.html 
      }
 }

查看完整示例: https : //spring.io/guides/gs/serving-web-content/

@Controller
public class WebController {
@GetMapping("/")

public String homePage() {
    return "index";
  }
}

我在 Spring 引导 3.0.7 中遇到了同样的问题,这对我有用:

将 controller 注释更改为@Controller@RequestMapping 欢迎方法应使用@GetMapping注释。

@Controller
@RequestMapping
public class HomeController {

    @GetMapping("/")
    public String welcome() {
        return "login";
    }
}

您可以通过两种方式解决此问题:

第一种方式:如果您希望继续使用 REST,您必须使用ModelAndView对象来呈现 HTML 页面。 一个例子是由 Happy Nguyen 发布的,我在这里再次发布:

@RequestMapping("/")
public ModelAndView index () {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("index");
    return modelAndView;
}

第二种方式:如果天气不重要,您是否继续使用 REST,那么您只需将@RestController更改为@Controller并确保您已经添加了Thymeleaf模板引擎。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM