Zak Dyer

Zak Dyer

1551243042

Error page in Spring Boot application with CookieLocaleResolver

I Have a Spring Boot application which has the org.springframework.web.servlet.i18n.CookieLocaleResolver for locale resolver. If there is a invalid language cookie like !en then there will be an exception java.lang.IllegalArgumentException: Locale part "!en" contains invalid characters.

The problem is this exception is not handled by Spring Boot instead it is forwarded to Servlet container. So the default error page of the the container is shown (In my case it is JBoss EAP 6) which will show the stacktrace.

Other exceptions from the controllers are handled properly. For example I have a controller mapping which will throw / by zero error which is handled properly.

I have tried error page configuration in web.xml as follows.

<error-page>
    <location>/500</location>
</error-page>

And mapped both /error and /500 to a MVC controller as follows.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.AbstractErrorController;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class CustomErrorController extends AbstractErrorController {
public static final String ERROR_500 = “/500”;
private static final String ERROR_PATH= “/error”;

@Autowired
public CustomErrorController(ErrorAttributes errorAttributes) {
    super(errorAttributes);
}


/**
 * Responsible for handling all errors and throw especial exceptions
 * for some HTTP status codes. Otherwise, it will return a map that
 * ultimately will be converted to a json error.
 */
@RequestMapping({ERROR_PATH,ERROR_500})
public ResponseEntity&lt;?&gt; handleErrors(HttpServletRequest request) {
    return ResponseEntity.status(getStatus(request)).body(getErrorAttributes(request, false));
}

@Override
public String getErrorPath() {
    return ERROR_PATH;
}

}

But still I’m getting the container’s default error page. How to resolve this.

Test application code is here

#spring-boot

What is GEEK

Buddha Community

Zachary Palmer

1551251573

The FrameworkServlet, which processes the request, determines the Locale prior to sending the request through the dispatcher as such an exception thrown when resolving the Locale doesn’t get caught in the processDispatchResult and as such doesn’t get handled like a normal WebMvc error. For context the FrameworkServlet is extended by the DispatcherServlet which overrides the buildLocaleContext(request) and that in turn calls the CookieLocaleResolver intance.

/**
 * Process this request, publishing an event regardless of the outcome.
 * <p>The actual event handling is performed by the abstract
 * {@link #doService} template method.
 */
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    long startTime = System.currentTimeMillis();
    Throwable failureCause = null;

    // Here the locale is determined
    LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
    LocaleContext localeContext = buildLocaleContext(request);

    RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

    initContextHolders(request, localeContext, requestAttributes);

    try {
        // here is where the WebMvc processing happens
        doService(request, response);
    }
    catch (ServletException ex) {
        failureCause = ex;
        throw ex;
    }
    catch (IOException ex) {
        failureCause = ex;
        throw ex;
    }
    catch (Throwable ex) {
        failureCause = ex;
        throw new NestedServletException("Request processing failed", ex);
    }

    finally {
        resetContextHolders(request, previousLocaleContext, previousAttributes);
        if (requestAttributes != null) {
            requestAttributes.requestCompleted();
        }

        if (logger.isDebugEnabled()) {
            if (failureCause != null) {
                this.logger.debug("Could not complete request", failureCause);
            }
            else {
                if (asyncManager.isConcurrentHandlingStarted()) {
                    logger.debug("Leaving response open for concurrent processing");
                }
                else {
                    this.logger.debug("Successfully completed request");
                }
            }
        }

        publishRequestHandledEvent(request, response, startTime, failureCause);
    }
}

DispatcherServlet method for buildLocaleContext()

/**
 * Build a LocaleContext for the given request, exposing the request's primary locale as current locale.
 * <p>The default implementation uses the dispatcher's LocaleResolver to obtain the current locale,
 * which might change during a request.
 * @param request current HTTP request
 * @return the corresponding LocaleContext
 */
@Override
protected LocaleContext buildLocaleContext(final HttpServletRequest request) {
    if (this.localeResolver instanceof LocaleContextResolver) {
        return ((LocaleContextResolver) this.localeResolver).resolveLocaleContext(request);
    }
    else {
        return new LocaleContext() {
            @Override
            public Locale getLocale() {
                return localeResolver.resolveLocale(request);
            }
        };
    }
}

Elthel Mario

1551251746

I think you also need to mention error-code in the params of your web.xml like below. It works for me.

<error-page>
    <error-code>500</error-code>
    <location>/500</location>
</error-page>

and then catch it in the controller

@RequestMapping(value = "/500", method = RequestMethod.GET)
public String error500(Model model) {
    //System.out.println("Error 500 ");
    return "500"; //will return the 500.jsp
}

Were  Joyce

Were Joyce

1620751200

How to Configure the Interceptor With Spring Boot Application

In the video in this article, we take a closer look at how to configure the interceptor with the Spring Boot application! Let’s take a look!

#spring boot #spring boot tutorial #interceptor #interceptors #spring boot interceptor #spring boot tutorial for beginners

Were  Joyce

Were Joyce

1620720872

Spring vs Spring BooDifference Between Spring and Spring Boot

As an extension of the Spring Framework, Spring Boot is widely used to make development on Spring faster, more efficient and convenient. In this article, we will look at some of the parameters were using Spring Boot can drastically reduce the time and effort required in application development.

What is Spring?

Spring Boot

Difference between Spring and Spring Boot

Advantages of Spring Boot over Spring

Conclusion

#full stack development #spring #spring and spring boot #spring boot

Sigrid  Farrell

Sigrid Farrell

1622601303

How to Configure log4j2 In a Spring Boot Application? | Spring Boot Logging [Video]

Configuring log4j2 is really quick and simple; this tutorial video explains the entire process in only 5 minutes, while you wait for your coffee to brew.

In the video below, we take a closer look at the How to configure log4j2 in the Spring boot application using log4j2.xml? | Spring Boot logging. Let’s get started!

#java #spring boot #video #log4j #spring boot tutorial #spring boot tutorial for beginners

Were  Joyce

Were Joyce

1620852060

How to Bootstrap a Spring Boot Application? Maven Project

In this article, take a closer look at how to bootstrap a Spring Boot application.

In the video below, we take a closer look at how to bootstrap a Spring Boot application. Let’s get started!

#java #tutorial #spring boot #maven #spring boot tutorial #bootstrap a spring boot application

Were  Joyce

Were Joyce

1624442460

Automate Spring Boot application deployments to Azure!

Today, we’re excited to announce the availability of the Azure Pipeline Task for deploying Spring Boot applications to Azure Spring Cloud. You can get started by building your pipelines using the Azure Spring Cloud task to automate Spring Boot application deployments to any number of environments and Azure Regions.

Over the past 18 months, we worked with many enterprise customers to learn about their scenarios including thoughts on automating end-to-end from idea to provisioning Azure resources to building Spring Boot applications to deploying those applications to production. Many of these customers have thousands of Spring Boot applications running in on-premises data centers. As they migrate these applications to the cloud, they need everything automated end-to-end to ensure repeatability and meet the requirements set forth by their IT departments and/or regulatory bodies. They require a fully-featured Continuous Integration / Continuous Delivery (CI/CD) service that can automatically deploy updated Spring Boot applications to Azure Spring Cloud. In many customer environments, they use Azure CLI in Azure Pipelines to automate Spring Boot application deployments to Azure, and they asked Microsoft for an Azure Spring Cloud task to ease their automation effort and delegate the maintenance of the deployment task to Microsoft. Now, using the new Azure Spring Cloud task, anyone can automate deployments straight to production or automate blue-green strategies to stage for testing and then set to production.

#[object object] #spring boot #azure #application deployments #automate spring boot application deployments to azure!