微服务架构之Spring Boot(三十四)

2022-04-07 20:00:49 浏览数 (1)

28.1.9 ConfigurableWebBindingInitializer

Spring MVC使用 WebBindingInitializer 为特定请求初始化 WebDataBinder 。如果您创建自己的 ConfigurableWebBindingInitializer

@Bean ,Spring Boot会自动配置Spring MVC以使用它。

28.1.10模板引擎

除REST Web服务外,您还可以使用Spring MVC来提供动态HTML内容。Spring MVC支持各种模板技术,包括Thymeleaf,FreeMarker和

JSP。此外,许多其他模板引擎包括他们自己的Spring MVC集成。

Spring Boot包括对以下模板引擎的自动配置支持:

FreeMarker的

Groovy的

Thymeleaf

胡子

如果可能,应该避免使用JSP。将它们与嵌入式servlet容器一起使用时有几个 已知的限制。

当您使用其中一个模板引擎和默认配置时,您的模板将从 src/main/resources/templates 自动获取。

根据您运行应用程序的方式,IntelliJ IDEA以不同方式对类路径进行排序。从主方法在IDE中运行应用程序会产生与使用Maven或

Gradle或其打包的jar运行应用程序时不同的顺序。这可能导致Spring Boot无法在类路径上找到模板。如果遇到此问题,可以在

IDE中重新排序类路径,以便首先放置模块的类和资源。或者,您可以配置模板前缀以搜索类路径上的每个 templates 目录,如

下所示:classpath*:/templates/ 。

28.1.11错误处理

默认情况下,Spring Boot提供 /error 映射,以合理的方式处理所有错误,并在servlet容器中注册为“全局”错误页面。对于计算机客户端,

它会生成一个JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个“whitelabel”错误视图,以HTML格

式呈现相同的数据(要自定义它,添加一个解析为 error 的 View )。要完全替换默认行为,您可以实现 ErrorController 并注册该类型的

bean定义或添加bean类型 ErrorAttributes 以使用现有机制但替换内容。

BasicErrorController 可以用作自定义 ErrorController 的基类。如果要为新内容类型添加处理程序,则此功能特别有用

(默认情况下,专门处理 text/html 并为其他所有内容提供后备)。为此,请扩展 BasicErrorController ,添加具

有 produces 属性的 @RequestMapping 的公共方法,并创建新类型的bean。

您还可以定义使用 @ControllerAdvice 注释的类,以自定义要为特定控制器和/或异常类型返回的JSON文档,如以下示例所示:

@ControllerAdvice(basePackageClasses = AcmeController.class)

public class AcmeControllerAdvice 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);

}

}

在前面的示例中,如果 YourException 在与 AcmeController 相同的包中定义的控制器抛出,则使用 CustomErrorType POJO的JSON表示而

不是 ErrorAttributes 表示。

自定义错误页面

如果要显示给定状态代码的自定义HTML错误页面,可以将文件添加到 /error 文件夹。错误页面可以是静态HTML(即,添加到任何静态资源

文件夹下),也可以使用模板构建。文件名应该是确切的状态代码或系列掩码。

例如,要将 404 映射到静态HTML文件,您的文件夹结构将如下所示:

src/

- main/

- java/

| <source code>

- resources/

- public/

- error/

| - 404.html

- <other public assets>

要使用FreeMarker模板映射所有 5xx 错误,您的文件夹结构如下:

src/

- main/

- java/

| <source code>

- resources/

- templates/

- error/

| - 5xx.ftl

- <other templates>

对于更复杂的映射,您还可以添加实现 ErrorViewResolver 接口的beans,如以下示例所示:

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 ...

}

}

您还可以使用常规的Spring MVC功能,例如 @ExceptionHandler 方法和 @ControllerAdvice 。ErrorController 然后选择任何未处理的

异常。

将错误页面映射到Spring MVC之外

对于不使用Spring MVC的应用程序,可以使用 ErrorPageRegistrar 接口直接注册 ErrorPages 。这种抽象直接与底层嵌入式servlet容器一起

工作,即使你没有Spring MVC DispatcherServlet 也可以工作。

@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"));

}

}

如果你注册 ErrorPage 的路径最终由 Filter 处理(如某些非Spring网页框架,如Jersey和Wicket),那么 Filter 必须显式注

册为 ERROR 调度程序,如以下示例所示:

@Bean

public FilterRegistrationBean myFilter() {

FilterRegistrationBean registration = new FilterRegistrationBean();

registration.setFilter(new MyFilter());

...

registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));

return registration;

}

请注意,默认值 FilterRegistrationBean 不包括 ERROR 调度程序类型。

小心:当部署到servlet容器时,Spring Boot使用其错误页面过滤器将具有错误状态的请求转发到相应的错误页面。如果尚未提交响应,则只能

将请求转发到正确的错误页面。缺省情况下,WebSphere Application Server 8.0及更高版本在成功完成servlet的服务方法后提交响应。您应

该通过将 com.ibm.ws.webcontainer.invokeFlushAfterService 设置为 false 来禁用此行为。

0 人点赞