ErrorPageFilter cannot find RequestDispatcher

The Spring Web MVC Framework (often referred to as "Spring MVC") is a rich "Model View Control" web framework. Spring MVC lets you create special @Controller or @RestController beans to handle HTTP requests. Methods in controllers that are mapped to HTTP are annotated with @RequestMapping.

      下面是一个@RestController 响应JSON数据的经典例子:
[java] view plain copy
<span style="font-size:14px;">@RestController  
@RequestMapping(value="/users")  
public class MyRestController {  
  
    @RequestMapping(value="/{user}", method=RequestMethod.GET)  
    public User getUser(@PathVariable Long user) {  
        // ...  
    }  
  
    @RequestMapping(value="/{user}/customers", method=RequestMethod.GET)  
    List<Customer> getUserCustomers(@PathVariable Long user) {  
        // ...  
    }  
  
    @RequestMapping(value="/{user}", method=RequestMethod.DELETE)  
    public User deleteUser(@PathVariable Long user) {  
        // ...  
    }  
  
}</span>  
Spring MVC is part of the core of the spring framework, details can be found in the reference documentation. There are also some guides covering Spring MVC available at spring.io/guides.

27.1.1 Spring MVC autoconfiguration


Spring Boot provides automatic configuration for Spring MVC to make many applications work well.

Auto-configuration follows the following features on the basis of Spring:

Contains ContentNegotiatingViewResolver and BeanNameViewResolver beans.
Supports server-side static resources, including support for WebJars (see below).
Automatically annotates Converter, GenericConverter, Formatter beans.
Supports HttpMessageConverters (see below).
Automatically annotates MessageCodesResolver (see below).
Supports static indexing .html .
Supports custom favicon (see below).
Automatically uses ConfigurableWebBindingInitializer bean (see below).
If you want to keep Spring Boot MVC features and want to add some additional MVC configuration (interceptors, formatters, view controls, etc.) , you can add your own @Configuration class of type WebMvcConfigurerAdapter and not use @EnableWebMvc. If you want to provide a custom RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver instance, you can declare a WebMvcRegistrationsAdapter instance to provide the above components;

If you want full Spring MVC control, you can add @EnableWebMvc to your own @Configuration annotation.    

27.1.2 HttpMessageConverters

Spring MVC uses the HttpMessageConverter interface to convert HTTP requests and responses. Obviously out of the box by default, for example objects can be automatically converted to JSON (using jackson library) or XML (using jackson XML extension if available otherwise JAXB). Strings are encoded in UTF-8 by default.

If you need to add or customize converters, you can use Spring Boot's HttpMessageConverters class:
[java] view plain copy
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;  
import org.springframework.context.annotation.*;  
import org.springframework.http.converter.*;  
  
@Configuration  
public class MyConfiguration {  
  
    @Bean  
    public HttpMessageConverters customConverters() {  
        HttpMessageConverter<?> additional = ...  
        HttpMessageConverter<?> another = ...  
        return new HttpMessageConverters(additional, another) ;  
    }  
  
}  

Any HttpMessageConverter bean present in the environment will be added to the converter list. So you may also consider overriding the default converter.

27.1.3 Custom JSON serialization and serialization

If you are using Jackson to serialize and deserialize JSON data, then you probably want to write your own JsonSerializer and JsonDeserializer classes. Custom serializers are usually registered with Jackson through a module, but Spring Boot provides a @JsonComponent annotation that allows it to be registered as Spring Beans right away.

You can use @JsonComponent directly on a JsonSerializer or JsonDeserializer implementation. Can also be used on inner classes that contain serialization/deserialization. For example:
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;

@JsonComponent
public class Example {

public static class Serializer extends JsonSerializer<SomeObject> {
// ...
}

public static class Deserializer extends JsonDeserializer<SomeObject> {
// ...
}

}

All @JsonComponent beans in the ApplicationContext will be automatically registered with Jackson, and since @JsonComponent uses the meta-annotation @Component, the usual component scanning rules also apply to @JsonComponent .

Spring Boot also provides the JsonObjectSerializer and JsonObjectDeserializer base classes to use the standard Jackson version when serializing objects. See the Javadoc for details.

27.1.4 MessageCodesResolver

Spring MVC has a strategy for generating error codes for bound error messages: MessageCodesResolver. If you set the spring.mvc.message-codes-resolver.format property to PREFIX_ERROR_CODE or POSTFIX_ERROR_CODE (refer to the enumeration in DefaultMessageCodesResolver.Format) then Spring Boot will create a message code converter for you.
27.1.5 Static Content
 By default Spring Boot treats a directory named /static (or /public or /resources or /META-INF/resources ) under the classpath or the root of the ServletContext as static content. It is implemented using the ResourceHttpRequestHandler in Spring MVC, so you can modify this behavior by adding your own WebMvcConfigurerAdapter and overriding the addResourceHandlers method.

In a standalone web application the default servlet in the container will also be started as a fallback to handle content under the ServletContext root that Spring decides not to handle. Usually this doesn't happen (unless you modify the default MVC configuration) because Spring can always handle requests through the DispatcherServlet .

Usually, resource files are mapped in the /** path, but you can change it via spring.mvc.static-path-pattern . For example, migrating all resources to /resources/** can be done with the following modification:
spring.mvc.static-path-pattern=/resources/**
You can also use spring.resources.static-locations (replace the default with a list of directory paths value) Custom static resource location. If you do this, the default welcome page will switch to the location you define for lookup, and if there is an index.html file in any of the locations you enable, then it will be used as the app's welcome page.

In addition to the standard static resource locations above, special cases apply to Webjars content. Any resources packaged in webjars format under the /webjars/** path will be loaded as jar files.


If your application will be packaged as a jar, do not use the src/main/webapp directory. Although this directory is a common standard, it only works with war packaging and is ignored by most build tools when generating jars.
Spring Boot also supports Spring MVC's advanced resource handling features, allowing for things like caching static resources or using URLs with versioned Webjars.

To use versioned Webjars URLs, just add the webjars-locator dependency. Then declare your Webjar, take jQuery for example like "/webjars/jquery/dist/jquery.min.js" in "/webjars/jquery/xyz/dist/jquery.min.js", where xyz is Webjars version of.

If you are using JBOOS, you need to declare webjars-locator-jboss-vfs dependency instead of webjars-locator; otherwise all Webjars will be handled as 404

To use caching, the following configuration configures a caching scheme for all static resources, effectively adding a content hash to URLs, like this
<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>:
spring.resources .chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**


Resource links using templates are rewritten at runtime due to the ResourceUrlEncodingFilter, which is automatically configured for Thymeleaf and FreeMarker. You can manually declare this filter when using JSPs. Macro/Auxiliary custom template and use ResourceUrlProvider to achieve

Renamed files are not supported when dynamic resources are loaded, such as after a JavaScript module is loaded. This is why other strategies are provided and allowed to be used together. A "fixed" strategy will add a static version string to the URL unless the filename changes:
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12
With the above configuration, in " JavaScript modules under /js/lib/" can use a fixed version policy "/v12/js/lib/mymodule.js" while other resources can still use <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>

See ResourceProperties for more supported operations.


This feature is fully documented in this dedicated blog post and in the Spring Framework reference documentation

27.1.6 Custom Favicon
Spring Boot will look for a favicon.ico in the configured static directory location and the classpath (in default order) root, and if it exists it will automatically be used as the application's icon.

27.1.7 ConfigurableWebBindingInitializer

Spring MVC uses WebBindingInitializer to initialize a WebDataBinder for a particular request. If you create your own ConfigurableWebBindingInitializer @Bean, Spring Boot will automatically configure Spring MVC to use it.

27.1.8 Template engines

In addition to serving as a REST web service, you can also use Spring MVC to serve dynamic HTML content. Spring MVC supports multiple templating technologies including Thymeleaf, FreeMarker and JSPs. Many other template engines have also released their own Spring MVC integration solutions.

Auto-configuration of the following template engines is supported within Spring Boot:
FreeMarker
Groovy
Thymeleaf
Mustache

Avoid using JSPs as much as possible, there are some known limitations when using embedded servlet containers

When you use one of the above template engines, your templates will automatically be loaded from src/main/resources/templates by default.


IntelliJ IDEA decides different classpaths depending on how you run your application. The order in which the application is run from the main method in the IDE and from the jar file packaged with Maven or Gradle is different. This will cause Spring Boot to fail to discover templates on the classpath. If you are affected by this issue, you can readjust the module level and resource priority in the IDE. Alternatively, you can configure the template prefix to search every template directory in the classpath: classpath*:/templates/.
27.1.9 Error Handling

Spring Boot provides a /error mapping by default to handle all errors in a reasonable way, which registers a global error page in the servlet container. On the client side, it returns a JSON response with error details, HTTP status and exception message. For the browser, it provides a white page error view that uses the same data in HTML format (if you want to customize it, you only need to add a view that resolves the error). To completely replace the default behavior, you need to implement ErrorController and register a bean of this type, or add a bean of type ErrorAttributes that uses the existing mechanism but replaces the content.


This BasicErrorController can be used as the base class for custom ErrorControllers. This is especially useful if you want to add a handler for new content types (the default is to explicitly handle text/html and return a callback). You just create your own class extending BasicErrorController and add a @RequestMapping with the produces attribute public method.

You can also customize the returned JSON document by adding @ControllerAdvice for a different controller or other type.
@ControllerAdvice(basePackageClasses = FooController.class)
public class FooControllerAdvice extends ResponseEntityExceptionHandler {

@ExceptionHandler(YourException.class)
@ResponseBody
ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
HttpStatus status = getStatus(request);
return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
}

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

}

In the above example, if any controller defined in the FooController package throws YourException , a json representing the CustomerErrorType object will be returned instead of the original ErrorAttributes object.

custom error page

If you want to customize the HTML error page for a given status code, you need to add the corresponding page under the /error folder. Error pages can either be built using static HTML (that is, added under any static resources folder) or using templates. But the filename must be an exact status code or mask.

For example, to map 404 to a static HTML file, your file structure should look like this:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404 .html
+- <other public assets>

To use a FreeMarker template to map all 5xx errors, you need a structure like this:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| + - 5xx.ftl
+- <other templates>

For more complex mappings, you need to add beans that implement the ErrorViewResolver interface.
public class MyErrorViewResolver implements ErrorViewResolver {

@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
// Use the request or status to optionally return a ModelAndView
return ...
}

}
You can also use normal SpringMVC features like @ExceptionHandler methods and @ControllerAdvice . Then ErrorController will take over any unhandled exceptions.

Mapping error pages outside of SpringMVC

For applications not using SpringMVC, you can use the ErrorPageRegistrar interface to register ErrorPages directly. Then even though you don't have SpringMVC's DispatcherServlet , the extraction will still work directly and efficiently under the embedded servlet container.
@Bean
public ErrorPageRegistrar errorPageRegistrar(){
return new MyErrorPageRegistrar();
}

// ...

private static class MyErrorPageRegistrar implements ErrorPageRegistrar {

@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
}

}

Note that if you register an ErrorPage on a path, make sure it is intercepted by a Filter (like some do not usually have Spring-web frameworks, such as Jersey and Wicket), and that the Filter needs to be explicitly registered as an ERROR dispatcher, For example:
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
( The default FilterRegistrationBean does not contain an ERROR dispatch type).

WebSphere application server error handling

Once published to a servlet container, Spring Boot uses its error page interceptor to forward requests with error status to the appropriate error page. The request will only be forwarded correctly if the response has not been submitted. Typically, WebSphere Application Server 8.0 and later will submit the response after completing a servlet service method. You need to turn off this behavior by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false.

27.1.10 Spring HATEOAS

If you want to develop a RESTful API for hypermedia, Spring Boot provides auto-configuration for Spring HATEOAS that works well for most applications. Auto-configuration replaces the need to use @EnableHypermediaSupport and register the number of beans to facilitate building hypermedia-based applications, including a LinkDiscoverers (for client-side support) and an ObjectMapper configuration to properly direct responses to the needs. ObjectMapper configuration needs to be based on spring.jackson.* properties or an existing Jackson2ObjectMapperBuilder bean.

You can control the configuration of Spring HATEOAS by using @EnableHypermediaSupport . Note that this will not show the definition of ObjectMapper mentioned above.

27.1.11 CORS Support

Cross-origin
resource sharing (CORS) is a W3C
specification implemented by most
browsers to allow you to easily distinguish which cross-origin requests are authorized, replacing insecure and less robust ones like IFRAME or JSONP.

In version 4.2, SpringMVC supports CORS very well. CORS configuration using controller methods annotated with @CrossOrigin in your Spring Boot application does not require any special configuration. Global CORS configuration is defined by registering a WebMvcConfigurer bean with a custom addCorsMappings(CorsRegistry) method:
@Configuration
public class MyConfiguration {

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}

27.2 JAX-RS 和Jersey

For the REST endpoint, if you prefer to use the JAX-RS design model, you can use any solution that can replace SpringMVC. Jersey 1.x and Apache CXF are well supported if you register a Jersey 1.x and Apache CXF Servlet or Filter as a @Bean in your application environment. Jersey 2.x started to have native support for Spring, so we provided her with auto-configuration support in Spring Boot as a start.

To start with Jersey 2.x, just add the spring-boot-starter-jersey dependency, and then configure a @Bean of type ResourceConfig in all your registered terminals:

@Component
public class JerseyConfig extends ResourceConfig {

public JerseyConfig() {
register(Endpoint.class);
}

}


Jersey has limited support for executable file scanning. For example she does not scan the terminal under WEB-INF/classes when running an executable war file. To avoid this limitation, packaging techniques are not recommended and endpoints should be registered individually using the register method as shown above.

You can also register any number of beans that implement ResourceConfigCustomizer for more customization needs.

All registered endpoints should be annotated with @Components with HTTP methods (like @GET etc.) For example:
@Component
@Path("/hello")
public class Endpoint {

@GET
public String message() {
return "Hello";
}

}
Since the terminal is a component of Spring, its life cycle is managed by Spring, so you can @Autowired dependency injection and use @Value to get external configuration values. Jersey servlets will be registered and mapped to /* by default. You can change this mapping rule by adding @ApplicationPath to your ResourceConfig.

Usually Jersey will be treated as a servlet named jerseyServletRegistration @Bean of type ServletRegistrationBean . By default, this servlet is lazy loaded unless you customize spring.jersey.servlet.load-on-startup . You can disable or override the above bean by creating a bean of the same name, or you can use an interceptor instead of the servlet by setting spring.jersey.type=filter (a bean is needed to replace or override jerseyFilterRegistration in this case). Servlets can configure the order via @Order (you can set spring.jersey.filter.order to enable). Both Servlet and Filter can be given initialization parameters through the map attribute specified by spring.jersey.init.*.

To give you an idea of ​​how to configure it you can refer to this Jersey example. Also give a Jersey 1.x example. Note that in the Jersey 1.x sample the Spring-boot maven plugin is configured to not package certain Jersey jars so that they can be scanned by the JAX_RS implementation (because they are required to be scanned into the Filter in the sample). You may need to do the same any time your JAX-RS methods are packaged as inline Jars.

27.3 Internal Servlet Container Support

Spring Boot introduces support for embedded Tomcat, Jetty, and Undertow servers. Developers only need to use the appropriate "Starter" to get a fully configured instance. The embedded service listens for HTTP requests on 8080 by default.


Note if you choose to use Tomcat on CentOS, by default, a temporary folder is required to store compiled JSPs, uploaded files, etc. This directory may be deleted by tmpwatch and cause your application to fail to load. To avoid this, the To happen, you need to configure your tmpwatch so that the tomcat.* directories are not deleted, or configure server.tomcat.basedir to have the embedded Tomcat use a different location.

27.3.1 Servlets, Interceptors, Listeners

When using the embedded servlet container, you can register servlets, Filtes and all listeners (such as HttpSessionListener) according to the Servlet Manual by using Spring beans or by scanning for servlet components.

Register Servlets, Interceptors, and Listeners as Spring beans

Any Servlet, Filter or Servlet *Listener instance is registered with the embedded container as a Spring bean. This is convenient for you to get a value configured during configuration from application.properties .

By default, if only one servlet in the environment will be mapped to / , in the case of multiple servlet beans, the bean name will be used as the path prefix. Interceptors are mapped to /*.

Convention-based mapping is not flexible enough, you can gain full control by using the ServletRegistrationBean, FilterRegistrationBean and ServletListenerRegistrationBean classes.

27.3.2 Servlet environment initialization

The embedded servlet container does not directly implement the Servlet 3.0+ javax.servlet.ServletContainerInitializer interface, or Spring's org.springframework.web.WebApplicationInitializer interface. This contrived porting reduces the risk of third-party libraries running in a war package breaking the Spring Boot application.

If you need to perform initialization of the Servlet environment in your Spring Boot application, you need to register a bean that implements the org.springframework.boot.context.embedded.ServletContextInitializer interface. This only onStartup method provides access to the ServletContext, which can be handy as an adapter to an existing WebApplicationInitializer if needed.

Scan for Servlets, Filters, and listeners

When using the embedded container, use @ServletComponentScan to automatically discover and register @WebServlet, @WebFilter, and @WebListener annotated classes.


@ServletComponentScan has no effect in a single container, because the discovery mechanism inside the container replaces her.

27.3.3 Embedded Web Application Environment

A new type of ApplicationContext is used in Spring Boot for the embedded servlet container. EmbeddedWebApplicationContext is a special WebApplicationContext that bootstraps by looking for a single EmbeddedServletContainerFactory bean. Usually TomcatEmbeddedServletContainerFactory, JettyEmbeddedServletContainerFactory, or UndertowEmbeddedServletContainerFactory will be automatically configured.


You usually don't need to know about these implementation classes. Most applications will automatically configure and create the ApplicationContext and EmbeddedServletContainerFactory for you.

27.3.4 Customizing the Embedded Servlet Container

Generic servlet container configuration can be set using Spring's Environment property. Usually you define it in your application.properties file.

Common service settings include:
Network settings: HTTP request listening port (server.port), binding interface address to server.address, etc.
Session settings: session persistence (server.session.persistence), session timeout (server.session.timeout), session data location (server.session.store-dir) and session-cookie configuration (server.session.cookie.* ).
Error management: error page location (server.error.path), etc.
SSL
HTTP compression
Spring Boot exposes the same settings whenever possible, but this is not necessarily appropriate. Namespaces provide server-specific customizations for this situation (see server.tomcat and server.undertow). For entities, the access log is configured with the signature of the embedded servlet container.


See the ServerProperties class for a complete list

Programmatically customize

If you need to configure your embedded servlet container programmatically, you can register a Spring bean that implements the EmbeddedServletContainerCustomizer interface. EmbeddedServletContainerCustomizer Access to ConfigurableEmbeddedServletContainer which provides many custom setup methods.
import org.springframework.boot.context.embedded.*;
import org.springframework.stereotype.Component;

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(9000);
}

}

Define ConfigurableEmbeddedServletContainer directly

If the above customization techniques are too restrictive, you can also register your own TomcatEmbeddedServletContainerFactory, JettyEmbeddedServletContainerFactory or UndertowEmbeddedServletContainerFactory bean.
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html "));
return factory;
}

Setters provide a lot of configuration options. Some protection methods 'hooks' are also provided to you so that you need to be more free to do things. See the source code for details.
37.3.5 JSP Limitations

When running a Spring Boot application with an embedded servlet container (packaged as an executable), there are some limitations to JSP support:
if you use Tomcat for War packaging, an executable war can run , can also be unpacked by standard containers (no restrictions, not limited to Tomcat). An executable JAR is not valid, because it is difficult to decode in Tomcat.
If you use Jetty to pack the war, you get an executable war that can also be unpacked by any standard container.
Undertow does not support JSPs
creating a custom error.jsp nor does it override the default error handling view which should be replaced by a custom error page.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325154928&siteId=291194637