0

After hours of reading different posts, example projects, and many different fixes, I solved an issue related to serving static content within my Spring Boot project- specifically errors I received from a link to a CSS in an html page. It was the less popular of two answers in this following link (excerpt below) that solved it for me.

Check the Controller classes for which annotation is used - @RestController or @Controller. Do not mix Rest API and MVC behaviour in one class. For MVC use @Controller and for REST API use @RestController

Spring Boot app not serving static content

In summary, after everything I tried (modifying application.properties to explicitly set static directory paths, moving the CSS file into many different folders, including the supposed standard set ones) the style sheet could not be found. BUT...Changing out @RestController for @Controller solved it for the following code.

@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;
    }
}

Question is, why? What is it about using a ModelAndView object in a @RestController class that prevented my html page from loading the CSS file? Or the reverse, what is it about simply using @Controller that made this instantly work?

Clearly, as a novice with Spring, I am missing something about how these different Controllers function with linked static content, but can't find out why.

Russell Longo
  • 23
  • 1
  • 3
  • maybe this can help you: [spring-controller-vs-restcontroller](https://www.baeldung.com/spring-controller-vs-restcontroller) – Dirk Deyne May 10 '20 at 07:39

1 Answers1

0

If you annotate a class with @RestController, you're telling Spring that you want to serialize an object and return it as JSON, or XML (definitely something other than an HTML page).

@Controller lets you choose to return an HTML page. (Or, if you additionally annotate your @RequestMapping / @GetMapping / @PostMapping with @ResponseBody, you can serialize an object and return it as JSON, or XML.)

Metroids
  • 18,999
  • 4
  • 41
  • 52
  • So even though I’ve specified the View and return data in the ModelAndView class, and it actually finds the HTML page in my project’s template directory and loads the page formatting correctly, something about the @RestController functionality prevents that portion of my HTML page that references a local static asset? Looking to clarify that I’m understanding what your answer is stating. – Russell Longo May 12 '20 at 11:43
  • In other words, the use of MVC in the @RestController can still find the HTML template, run the Thymeleaf script against the data I pass in the MVC object, but cannot used referenced local static assets referenced through links, correct? I believe I was able to load an internet Bootstrap link, just no link local pointing my project directories would work. – Russell Longo May 12 '20 at 11:43
  • I'm not 100% sure, but the `content-type` of the return might be something that the browser doesn't expect. For example, if the content-type it's returning is `text/plain` then the browser might not even be trying to load the static assets (because it only does that for `text/html`). You should be able to use developer tools network tab to verify this (does it even attempt to load those external resources, and if it does what is returning?) – Metroids May 12 '20 at 14:09