在 Spring Project 中提供静态内容方面,@RestController 与 @Controller 的区别是啥?

Posted

技术标签:

【中文标题】在 Spring Project 中提供静态内容方面,@RestController 与 @Controller 的区别是啥?【英文标题】:Wju a distinction in @RestController vs @Controller with regards to serving of static content in Spring Project?在 Spring Project 中提供静态内容方面,@RestController 与 @Controller 的区别是什么? 【发布时间】:2020-08-25 16:22:26 【问题描述】:

经过数小时阅读不同的帖子、示例项目和许多不同的修复后,我解决了与在我的 Spring Boot 项目中提供静态内容相关的问题 - 特别是我从 html 页面中的 CSS 链接收到的错误。在以下链接(以下摘录)中为我解决了这个问题的两个答案中不太受欢迎的答案。

检查使用注解的控制器类 - @RestController 或 @Controller。不要在一个类中混合使用 Rest API 和 MVC 行为。对于 MVC,使用 @Controller,对于 REST API,使用 @RestController

Spring Boot app not serving static content

总之,在我尝试了一切(修改 application.properties 以显式设置静态目录路径,将 CSS 文件移动到许多不同的文件夹中,包括假定的标准集的文件夹)之后,找不到样式表。但是...将@RestController 换成@Controller 解决了以下代码。

@Controller
public class MVCController 
    @Autowired
    ThingdefstatsviewRepository defstatviewRepository;
    @Autowired
    ThingDefRecord thingDefRecord;

    @GetMapping(path="/characterdef/defid")
    public ModelAndView thymeLeafCharacterDefByID(@PathVariable String defid) 
        Long id = Long.parseLong(defid);
        thingDefRecord.loadAllStats(id);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("CharacterPage.html");
        //Adds an attribute to the model as a name/value(object) pair
        modelAndView.addObject("thingstats", thingDefRecord);
        return modelAndView;
    

问题是,为什么?在 @RestController 类中使用 ModelAndView 对象会阻止我的 html 页面加载 CSS 文件是怎么回事?或者反过来,简单地使用@Controller 让它立即工作的原因是什么?

显然,作为 Spring 的新手,我错过了有关这些不同控制器如何与链接的静态内容一起工作的一些信息,但无法找出原因。

【问题讨论】:

也许这可以帮助你:spring-controller-vs-restcontroller 【参考方案1】:

如果你用@RestController 注释一个类,你就是在告诉 Spring 你想要序列化一个对象并将它作为 JSON 或 XML(绝对不是 HTML 页面)返回。

@Controller 允许您选择返回 HTML 页面。 (或者,如果您使用@ResponseBody 额外注释您的@RequestMapping / @GetMapping / @PostMapping,您可以序列化一个对象并将其作为JSON 或XML 返回。)

【讨论】:

因此,即使我在 ModelAndView 类中指定了视图并返回数据,它实际上在我的项目模板目录中找到了 HTML 页面并正确加载了页面格式,这与 @RestController 功能有关阻止我的 HTML 页面中引用本地静态资产的那部分?希望澄清一下,我理解您的回答。 也就是说在@RestController中使用MVC仍然可以找到HTML模板,针对我传入MVC对象的数据运行Thymeleaf脚本,但是不能使用通过引用的本地静态资产链接,对吗?我相信我能够加载互联网引导链接,只是没有指向我的项目目录的本地链接。 我不是 100% 确定,但是返回的 content-type 可能是浏览器没有预料到的。例如,如果它返回的内容类型是text/plain,那么浏览器甚至可能不会尝试加载静态资源(因为它只对text/html 这样做)。您应该能够使用开发人员工具的网络选项卡来验证这一点(它是否甚至尝试加载那些外部资源,如果它确实返回了什么?)

以上是关于在 Spring Project 中提供静态内容方面,@RestController 与 @Controller 的区别是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在配置中定义servlet路径时如何在spring boot中提供静态内容

Spring boot:提供公共和私有(受限)静态内容

尽管使用 @RequestMapping("**") 在 Spring Boot 中提供静态内容

Spring Boot with Security不提供我的静态内容

Spring Boot不提供静态内容

Spring Security 拒绝提供静态内容(Javascript 文件)