Sahil
Sahil

Reputation: 71

Getting resource not found when try to return html page from controller

I am unable to render html page in springboot. Here is code...

@RestController
    public class ProductController {
        @Autowired
        ProductService service;
    
        @InitBinder
        public void initBinder(WebDataBinder webDataBinder) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
            dateFormat.setLenient(false);
            webDataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        }
        
        @RequestMapping(value = { "/", "/home" })
        public ModelAndView home() {
            System.out.println("sdasasas");
            return new ModelAndView("home");
        }
    
    

but whenever i hit http://localhost:8080/home it shows following logs

-8080-exec-4] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9,*/*;q=0.8]
2019-07-31 16:05:25.354 DEBUG 14850 --- [nio-8080-exec-4] o.s.w.servlet.view.InternalResourceView  : View name 'home', model {}
2019-07-31 16:05:25.354 DEBUG 14850 --- [nio-8080-exec-4] o.s.w.servlet.view.InternalResourceView  : Forwarding to [/WEB-INF/html/home.html]
2019-07-31 16:05:25.354 DEBUG 14850 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet        : "FORWARD" dispatch for GET "/WEB-INF/html/home.html", parameters={}
2019-07-31 16:05:25.356 DEBUG 14850 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/","/"]
2019-07-31 16:05:25.356  WARN 14850 --- [nio-8080-exec-4] o.s.w.s.r.ResourceHttpRequestHandler     : Path with "WEB-INF" or "META-INF": [WEB-INF/html/home.html]
2019-07-31 16:05:25.356 DEBUG 14850 --- [nio-8080-exec-4] o.s.w.s.r.ResourceHttpRequestHandler     : Resource not found
2019-07-31 16:05:25.357 DEBUG 14850 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet        : Exiting from "FORWARD" dispatch, status 404
2019-07-31 16:05:25.357 DEBUG 14850 --- [nio-8080-exec-4] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2019-07-31 16:05:25.357 DEBUG 14850 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet        : Completed 404 NOT_FOUND
2019-07-31 16:05:25.357 DEBUG 14850 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters={}

Upvotes: 3

Views: 9122

Answers (5)

rahuljain
rahuljain

Reputation: 1

Please check your project structure. The class where you are calling SpringApplication.run(XXX.class, args), hierarchy wise should be on top, and then other classes where you are using @RestController.

Upvotes: 0

ANUP SAJJAN
ANUP SAJJAN

Reputation: 1958

If you are returning a view page like .jsp from the controller, and it's throwing an error saying cannot locate resource .jsp or 404 not found, then try adding these dependencies to your pom file, it worked for me.

 <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>

Upvotes: 1

Romil Patel
Romil Patel

Reputation: 13727

Avoid @RestController for MVC Based Application which has to return a view. It is mainly used for REST APIs. While @Controller can return a view

More On @RestController:

enter image description here

  • This annotation is a specialized version of @Controller which adds @Controller and @ResponseBody annotation automatically. so we do not have to add @ResponseBody to our mapping methods. That means @ResponseBody is default active.
  • If you use @RestController you cannot return a view (By using Viewresolver in Spring/Spring-Boot)
  • @RestController also converts the response to JSON/XML automatically as @ResponseBody makes the returned objects to something that could be in the body, e.g. JSON or XML

Controller vs RestController


@RestController
    public class ProductController {
        @Autowired
        ProductService service;

        @RequestMapping(value = { "/", "/home" })
        public @ResponseBody ModelAndView home() {
            System.out.println("sdasasas");
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("home");
            return modelAndView;
        }
}

Project Structure enter image description here

No need to specify spring.mvc.view.prefix=/WEB-INF/html/ spring.mvc.view.suffix=.html

Also, make sure you don't have any additional class with @EnableWebMvc annotation. This can mess up the spring-boot autoconfiguration.

Upvotes: 2

Sivakumar Neelakandan
Sivakumar Neelakandan

Reputation: 36

You should always use @Controller Annotation while using Spring MVC. @RestController is different from @Controller.

@Controller returns a view, used in MVC applications,

While @RestController returns a response(Mostly Json), it converts your your java object to Json by using Jackson jar, and these are used for api's.

Upvotes: 2

Rajendra Gupta
Rajendra Gupta

Reputation: 379

@RestController is not meant to be used to return views to be resolved. It is supposed to return data which will be written to the body of the response

        @RestController     //change it to @Controller
        public class ProductController {
        @Autowired
        ProductService service;

This difference between @Controller and the @RestController annotation is that @Controller is to create a Map of model object and find a view but the @RestController simply returns the object and object data is directly written into HTTP response as JSON or XML.

Upvotes: 1

Related Questions