spring - This application has no explicit mapping for /error

spring – This application has no explicit mapping for /error

spring – This application has no explicit mapping for /error

Make sure that your main class is in a root package above other classes.

When you run a Spring Boot Application, (i.e. a class annotated with @SpringBootApplication), Spring will only scan the classes below your main class package.

com
   +- APP
         +- Application.java  <--- your main class should be here, above your controller classes
         |
         +- model
         |   +- user.java
         +- controller
             +- UserController.java

When we create a Spring boot application we annotate it with @SpringBootApplication annotation. This annotation wraps up many other necessary annotations for the application to work. One such annotation is @ComponentScan annotation. This annotation tells Spring to look for Spring components and configure the application to run.

Your application class needs to be top of your package hierarchy, so that Spring can scan sub-packages and find out the other required components.

package com.test.spring.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

Below code snippet works as the controller package is under com.test.spring.boot package

package com.test.spring.boot.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

    @RequestMapping(/)
    public String home(){
        return Hello World!;
    }
}

Below code snippet does NOT Work as the controller package is NOT under com.test.spring.boot package

package com.test.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

     @RequestMapping(/)
     public String home(){
         return Hello World!;
     }
 }

From Spring Boot documentation:

Many Spring Boot developers always have their main class annotated
with @Configuration, @EnableAutoConfiguration and @ComponentScan.
Since these annotations are so frequently used together (especially if
you follow the best practices above), Spring Boot provides a
convenient @SpringBootApplication alternative.

The @SpringBootApplication annotation is equivalent to using
@Configuration, @EnableAutoConfiguration and @ComponentScan with their
default attributes

spring – This application has no explicit mapping for /error

You can solve this by adding an ErrorController in your application. You can have the error controller return a view that you need.

Error Controller in my application looks like below:

import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Basic Controller which is called for unhandled errors
 */
@Controller
public class AppErrorController implements ErrorController{

    /**
     * Error Attributes in the Application
     */
    private ErrorAttributes errorAttributes;

    private final static String ERROR_PATH = /error;

    /**
     * Controller for the Error Controller
     * @param errorAttributes
     */
    public AppErrorController(ErrorAttributes errorAttributes) {
        this.errorAttributes = errorAttributes;
    }

    /**
     * Supports the HTML Error View
     * @param request
     * @return
     */
    @RequestMapping(value = ERROR_PATH, produces = text/html)
    public ModelAndView errorHtml(HttpServletRequest request) {
        return new ModelAndView(/errors/error, getErrorAttributes(request, false));
    }

    /**
     * Supports other formats like JSON, XML
     * @param request
     * @return
     */
    @RequestMapping(value = ERROR_PATH)
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request, getTraceParameter(request));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<Map<String, Object>>(body, status);
    }

    /**
     * Returns the path of the error page.
     *
     * @return the error path
     */
    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }


    private boolean getTraceParameter(HttpServletRequest request) {
        String parameter = request.getParameter(trace);
        if (parameter == null) {
            return false;
        }
        return !false.equals(parameter.toLowerCase());
    }

    private Map<String, Object> getErrorAttributes(HttpServletRequest request,
                                                   boolean includeStackTrace) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(request);
        return this.errorAttributes.getErrorAttributes(requestAttributes,
                includeStackTrace);
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request
                .getAttribute(javax.servlet.error.status_code);
        if (statusCode != null) {
            try {
                return HttpStatus.valueOf(statusCode);
            }
            catch (Exception ex) {
            }
        }
        return HttpStatus.INTERNAL_SERVER_ERROR;
    }
}

The above class is based on Springs BasicErrorController class.

You can instantiate the above ErrorController like this in a @Configuration file:

 @Autowired
 private ErrorAttributes errorAttributes;

 @Bean
 public AppErrorController appErrorController(){return new AppErrorController(errorAttributes);}

You can choose override the default ErrorAttributes by implementing ErrorAttributes. But in most cases the DefaultErrorAttributes should suffice.

Related posts on spring  :

Leave a Reply

Your email address will not be published.