【问题标题】:How to return a html page from a restful controller in spring boot?如何在spring boot中从restful控制器返回一个html页面?
【发布时间】:2016-12-06 15:33:57
【问题描述】:

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

这是我的控制器代码:

@RestController
public class HomeController {

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

这是我的项目结构:

[

【问题讨论】:

  • 尝试添加一个 servlet 以指向 index.html @ServletComponentScan 然后添加 @WebSevlet(urlPatterns = "") MainIndex

标签: java html spring spring-boot controller


【解决方案1】:

当像这样使用@RestController 时:

@RestController
public class HomeController {

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

这和你在普通控制器中做的一样:

@Controller
public class HomeController {

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

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

这就是为什么您在回复中只收到login

【讨论】:

  • 我很困惑。是什么问题以及如何解决?
  • @Itération122442 您应该对类使用 Controller 注释,并且应该从名为 welcome() 的方法中删除 ResponseBody 注释
【解决方案2】:

按照以下步骤操作:

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

  2. @RestController 替换为@Controller

  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>`
    

【讨论】:

  • 添加spring-boot-starter-thymeleaf依赖后,视图被解析
  • 仅使用 spring-starter-web 依赖项,我就可以通过键入 localhost: 8080/helloworld.html(全名)来提供位于 src/main/resources/static 内的 html 页面。但是使用 thmleaf 它会自动映射到 html 文件。所以我的问题是否有任何选项可以通过包含 spring-starter-web 依赖项来通过休息端点提供文件
  • 使用@Controller 解决了问题并返回了视图而不是字符串
【解决方案3】:

你可以试试ModelAndView:

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

【讨论】:

    【解决方案4】:

    @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 文件夹中,并且调用类似,现在唯一的区别在于视图名称,因为 tymeleaf 使用 .html 作为默认值。

    //  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";
      }
    }
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          我做了三件事:

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

          不需要特别的依赖

          【讨论】:

            【解决方案8】:

            在我将此依赖项添加到 pom 文件中之前,来自 Kukkuz 的答案对我不起作用:

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

            来自指南here

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

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

            【讨论】:

              【解决方案9】:

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

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

              【讨论】:

                【解决方案10】:

                @RestController 替换为@Controller

                【讨论】:

                • 如果你添加一些解释你的答案的cmets会更好。
                【解决方案11】:

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

                【讨论】:

                  【解决方案12】:

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

                  如果你想用这个名字显示视图,你需要使用 Spring MVC,see this example

                  【讨论】:

                    【解决方案13】:

                    你在这里返回的String

                     return "login";
                    

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

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

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

                    你可以通过这个answer on the question Spring boot service to download a file

                    【讨论】:

                      【解决方案14】:
                      @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";
                          }
                      }
                      

                      这将返回字符串登录

                      【讨论】:

                        【解决方案15】:

                        在用 @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,则返回简单字符串将不起作用,并且该字符串将被解释为普通字符串而不是 JSP 视图名称。


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

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

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

                        【讨论】:

                          【解决方案16】:

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

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

                          【讨论】:

                            【解决方案17】:

                            您可以像这样在 RequestMapping 中指定 GET 或 POST 方法:-

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

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

                            【讨论】:

                              【解决方案18】:

                              最正确和现代的形式是使用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/

                              【讨论】:

                                【解决方案19】:
                                @Controller
                                public class WebController {
                                @GetMapping("/")
                                
                                public String homePage() {
                                    return "index";
                                  }
                                }
                                

                                【讨论】:

                                • 有什么描述吗?
                                • 这也适用于 spring.mvc.view.prefix: /WEB-INF/jsp/ spring.mvc.view.suffix: .jsp
                                【解决方案20】:

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

                                第一种方式:如果您希望继续使用 REST,您必须使用 ModelAndView 对象来呈现 HTML 页面。 Happy Nguyen 正在发布一个示例,我将在此处再次发布:

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

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

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2020-09-05
                                  • 1970-01-01
                                  • 2020-01-26
                                  • 2018-07-14
                                  • 1970-01-01
                                  • 2016-12-31
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多