SpringBoot 很适合开发 web程序。你可以使用内嵌的 HTTP server (tomcat、jetty、undertow、netty)来创建web程序。大多数的web程序使用 spring-boot-starter-web 模块来构建。你也可以使用 spring-boot-starter-webflux 来构建响应式 web 程序。
如果还没有开发过 SpringBoot web 程序,你可以使用 Hello World 示例尝试一下。
7.1 The Spring Web MVC Framework
Spring Web MVC Framework 通常简称为 Spring MVC,一个 模型-视图-控制器框架。Spring MVC 容许你在 HTTP 入口类的 bean 上(Controller层)添加 @Controller 和 @RestController 注解。通过 @RequestMapping 注解将具体的请求映射到具体的方法上。
下面的代码显示了一个典型的@RestController,它提供JSON数据:
@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 getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
}
Spring MVC 是 Spring Framework 核心框架的一部分,详细的信息请参考 reference documentation。也有一些其他的内容可以参考 spring.io/guides
7.1.1 Spring MVC Auto-configuration
SpringBoot 为 Spring MVC 提供了自动配置功能可用在大多数的应用程序中。
自动配置(Auto-configuration)会在 Spring 基础上添加以下特性:
包含 of ContentNegotiatingViewResolver 和 BeanNameViewResolver beans.
Support for serving static resources(支持静态资源), including support for WebJars (covered later in this document 参考 7.1.5 章节内容)).
自动注册 Converter, GenericConverter, and Formatter beans.
支持 HttpMessageConverters (参考 7.1.2 章节).
自动注册 MessageCodesResolver (参考 7.1.4 章节).
Static index.html support.
Custom Favicon support (参考 7.1.7章节).
自动使用 of a ConfigurableWebBindingInitializer bean (参考 7.1.9 章节).
如果你想要保留 Spring MVC 的定制配置且想要进行更多的定制(拦截器,格式化程序,视图控制器和其他功能)。您可以添加自定义的类型为WebMvcConfigurer的@Configuration类,但不添加@EnableWebMvc。
Spring MVC 使用 HttpMessageConverter 接口转换 HTTP请求信息和响应信息,默认使用此消息转换器。比如,对象可以自动转换为 JSON (使用 JACKSON 类库)或者 XML(by using the Jackson XML extension, if available, or by using JAXB if the Jackson XML extension is not available) 。默认编码是 UTF-8.
如果使用Jackson序列化和反序列化JSON数据,则可能要编写自己的JsonSerializer和JsonDeserializer类。自定义序列化程序通常是通过模块向Jackson进行注册的(registered with Jackson through a module),但是 SpringBoot 提供了一个注解 @JsonComponent 可以是注册变得更加容易。
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 {
// ...
}
public static class Deserializer extends JsonDeserializer {
// ...
}
}
Spring Boot还提供了JsonObjectSerializer和JsonObjectDeserializer基类,这些基类在序列化对象时为标准Jackson版本提供了有用的替代方法。See JsonObjectSerializer and JsonObjectDeserializer in the Javadoc for details
7.1.4 MessageCodesResolver
Spring MVC has a strategy for generating error codes for rendering error messages from binding errors: MessageCodesResolver. If you set the spring.mvc.message-codes-resolver-format property PREFIX_ERROR_CODE or POSTFIX_ERROR_CODE, Spring Boot creates one for you (see the enumeration in DefaultMessageCodesResolver.Format).
Spring MVC 有一种从错误消息生成错误代码的机制: MessageCodesResolver.你可以设置 spring.mvc.message-codes-resolver-format 的值为 PREFIX_ERROR_CODE 或者 POSTFIX_ERROR_CODE,see the enumeration in DefaultMessageCodesResolver.Format
如果您的应用程序打包为jar,请不要使用src/main/webapp目录。虽然这个目录是一个通用的标准,但是它只适用于 war 包,如果你生成一个jar,它会被大多数构建工具忽略。
7.1.6 Welcome Page
Spring Boot supports both static and templated welcome pages. It first looks for an index.html file in the configured static content locations. If one is not found, it then looks for an index template. If either is found, it is automatically used as the welcome page of the application.
Spring Boot支持静态和模板的欢迎页面。 它首先在配置的静态内容位置中查找index.html文件。 如果未找到,则寻找 index 模板。如果一个都没有找到,它将自动用作应用程序的欢迎页面。
spring.mvc.contentnegotiation.favor-parameter=true
#We can change the parameter name, which is "format" by default:
#spring.mvc.contentnegotiation.parameter-name=myparam
#We can also register additional file extensions/media types with:
spring.mvc.contentnegotiation.media-types.markdown=text/markdown
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true
#You can also register additional file extensions/media types with:
#spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc
7.1.9 ConfigurableWebBindingInitializer
Spring MVC uses a WebBindingInitializer to initialize a WebDataBinder for a particular request. If you create your own ConfigurableWebBindingInitializer @Bean, Spring Boot automatically configures Spring MVC to use it.
7.1.10 Template Engines
除了REST Web服务之外,您还可以使用Spring MVC来提供动态HTML内容。 Spring MVC支持各种模板技术,包括Thymeleaf,FreeMarker和JSP。 同样,许多其他模板引擎包括它们自己的Spring MVC集成。
Spring Boot includes auto-configuration support for the following templating engines:
Depending on how you run your application, IntelliJ IDEA orders the classpath differently. Running your application in the IDE from its main method results in a different ordering than when you run your application by using Maven or Gradle or from its packaged jar. This can cause Spring Boot to fail to find the templates on the classpath. If you have this problem, you can reorder the classpath in the IDE to place the module’s classes and resources first. Alternatively, you can configure the template prefix to search every templates directory on the classpath, as follows: classpath:/templates/. 大致意思:配置文件加载和程序运行的方式有关系,在 IDEA 中类路径(classpath)有所不同,如果遇到问题可以修改一个配置: classpath:/templates/.
@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);
}
}
In the preceding example, if YourException is thrown by a controller defined in the same package as AcmeController, a JSON representation of the CustomErrorType POJO is used instead of the ErrorAttributes representation.
7.1.11.1 Custom Error Pages
如果你要根据不同的状态码显示自定义的 HTML 错误页面,你可以添加页面到 /error 文件夹下面。错误的页面可以是静态的HTML 页面或者动态模板。文件的名称需要和状态码保持一致。
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map model) {
// Use the request or status to optionally return a ModelAndView
return ...
}
}
7.1.11.2 Mapping Error Pages outside of 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"));
}
}
If you register an ErrorPage with a path that ends up being handled by a Filter (as is common with some non-Spring web frameworks, like Jersey and Wicket), then the Filter has to be explicitly registered as an ERROR dispatcher, as shown in the following example:
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
请注意,默认的FilterRegistrationBean不包含ERROR调度程序类型。
注意:当Spring Boot部署到servlet容器时,将使用其错误页面过滤器将具有错误状态的请求转发到相应的错误页面。 如果尚未提交响应,则只能将请求转发到正确的错误页面。 缺省情况下,WebSphere Application Server 8.0及更高版本在成功完成servlet的服务方法后提交响应。 您应该通过将com.ibm.ws.webcontainer.invokeFlushAfterService设置为false来禁用此行为。
7.1.12 Spring HATEOAS
If you develop a RESTful API that makes use of hypermedia, Spring Boot provides auto-configuration for Spring HATEOAS that works well with most applications. The auto-configuration replaces the need to use @EnableHypermediaSupport and registers a number of beans to ease building hypermedia-based applications, including a LinkDiscoverers (for client side support) and an ObjectMapper configured to correctly marshal responses into the desired representation. The ObjectMapper is customized by setting the various spring.jackson.* properties or, if one exists, by a Jackson2ObjectMapperBuilder bean.
You can take control of Spring HATEOAS’s configuration by using @EnableHypermediaSupport. Note that doing so disables the ObjectMapper customization described earlier.
@Configuration(proxyBeanMethods = false)
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
7.2 The Spring Webflux Framework
Spring Webflux 是 Spring Framework5.0 引进的新的响应式web框架,与 Spring MVC 有所不同,它不需要 Servlet API,支持 完全异步、非阻塞,and implements the Reactive Streams specification through the Reactor project.
Spring WebFlux有两种风格:功能性和基于注释的。基于注释的模式非常接近于Spring MVC模式,如下面的示例所示
@RestController
@RequestMapping("/users")
public class MyRestController {
@GetMapping("/{user}")
public Mono getUser(@PathVariable Long user) {
// ...
}
@GetMapping("/{user}/customers")
public Flux getUserCustomers(@PathVariable Long user) {
// ...
}
@DeleteMapping("/{user}")
public Mono deleteUser(@PathVariable Long user) {
// ...
}
}
WebFlux.fn 是函数变体,它将路由配置与请求的实际处理分离开来,如下面的示例所示:
@Configuration(proxyBeanMethods = false)
public class RoutingConfiguration {
@Bean
public RouterFunction monoRouterFunction(UserHandler userHandler) {
return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
.andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
.andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
}
}
@Component
public class UserHandler {
public Mono getUser(ServerRequest request) {
// ...
}
public Mono getUserCustomers(ServerRequest request) {
// ...
}
public Mono deleteUser(ServerRequest request) {
// ...
}
}
Adding both spring-boot-starter-web and spring-boot-starter-webflux modules in your application results in Spring Boot auto-configuring Spring MVC, not WebFlux. This behavior has been chosen because many Spring developers add spring-boot-starter-webflux to their Spring MVC application to use the reactive WebClient. You can still enforce your choice by setting the chosen application type to SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE). 如果在程序中添加了 spring-boot-starter-web 和 spring-boot-starter-webflux 模块,springBoot 会自动注册 SpringMVC 而不是 webflux。This behavior has been chosen because many Spring developers add spring-boot-starter-webflux to their Spring MVC application to use the reactive WebClient。你可以通过下面代码进行强制设置:
Spring Boot为Spring WebFlux提供了自动配置,可以很好地与大多数应用程序配合使用。
自动配置在Spring默认设置的基础上增加了以下特性
Configuring codecs for HttpMessageReader and HttpMessageWriter instances (described later in this document). 为HttpMessageReader和HttpMessageWriter实例配置编解码器
Support for serving static resources, including support for WebJars (described later in this document). 支持提供静态资源,包括对webjar的支持
7.2.2 Http Codes with HTtpMessageReaders and HttpMessageWriters
Spring Webflux 使用 HttpMessageReader 和 HttpMessageWriter 接口来转换 HTTP请求和响应。They are configured with CodecConfigurer to have sensible defaults by looking at the libraries available in your classpath.
Spring Boot provides dedicated configuration properties for codecs, spring.codec.. It also applies further customization by using CodecCustomizer instances. For example, spring.jackson. configuration keys are applied to the Jackson codec.
Spring Boot为编解码器 spring.codec.* 提供了专用的配置属性。 它还通过使用 CodecCustomizer 实例应用进一步的自定义。 例如,将 spring.jackson.* 配置应用于 Jackson 编解码器。
If you need to add or customize codecs, you can create a custom CodecCustomizer component, as shown in the following example:
import org.springframework.boot.web.codec.CodecCustomizer;
@Configuration(proxyBeanMethods = false)
public class MyConfiguration {
@Bean
public CodecCustomizer myCodecCustomizer() {
return codecConfigurer -> {
// ...
};
}
}
You can also leverage Boot’s custom JSON serializers and deserializers(参考 7.1.3 章节).
7.2.3 Static Content
默认,SpringBoot 的静态资源从 /static (or /public or resources or /META-INF/resources)in classpath.它使用来自Spring WebFlux的ResourceWebHandler,因此您可以通过添加自己的WebFluxConfigurer并覆盖addResourceHandlers方法来修改行为。
By default, resources are mapped on /, but you can tune that by setting the spring.webflux.static-path-pattern property. For instance, relocating all resources to /resources/ can be achieved as follows:
Spring WebFlux applications do not strictly depend on the Servlet API, so they cannot be deployed as war files and do not use the src/main/webapp directory.
Spring Boot includes auto-configuration support for the following templating engines:
FreeMarker
Thymeleaf
Mustache
When you use one of these templating engines with the default configuration, your templates are picked up automatically from src/main/resources/templates。
7.2.5 Error Handling
SpringBoot 提供了 WebExceptionHandler 在合适的途径来处理所有的错误。它在处理顺序中的位置紧接在WebFlux提供的处理程序之前,该处理程序被认为是最后一个。它为客户端以 JSON 格式提供详细的错误信息:HTTP status 和 错误消息。对于浏览器,它会返回一个空白的错误页面包括同样的错误数据。你可以自定义 HTML 模板来自定义错误信息的显示。
If you prefer the JAX-RS programming model for REST endpoints, you can use one of the available implementations instead of Spring MVC. Jersey and Apache CXF work quite well out of the box. CXF requires you to register its Servlet or Filter as a @Bean in your application context. Jersey has some native Spring support, so we also provide auto-configuration support for it in Spring Boot, together with a starter.
7.4 Embedded Servlet Contaner Support
Spring Boot includes support for embedded Tomcat, Jetty, and Undertow servers. Most developers use the appropriate “Starter” to obtain a fully configured instance. By default, the embedded server listens for HTTP requests on port 8080.
It is usually safe to leave Filter beans unordered. If a specific order is required, you should annotate the Filter with @Order or make it implement Ordered. You cannot configure the order of a Filter by annotating its bean method with @Order. If you cannot change the Filter class to add @Order or implement Ordered, you must define a FilterRegistrationBean for the Filter and set the registration bean’s order using the setOrder(int) method. Avoid configuring a Filter that reads the request body at Ordered.HIGHEST_PRECEDENCE, since it might go against the character encoding configuration of your application. If a Servlet filter wraps the request, it should be configured with an order that is less than or equal to OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER.
常用的 Servlet 配置可以使用 Spring Environment 属性配置,通常我们使用 application.properties 配置文件。
常用服务配置:
Network settings: Listen port for incoming HTTP requests (server.port), interface address to bind to server.address, and so on.
Session settings: Whether the session is persistent (server.servlet.session.persistent), session timeout (server.servlet.session.timeout), location of session data (server.servlet.session.store-dir), and session-cookie configuration (server.servlet.session.cookie.*).
Error management: Location of the error page (server.error.path) and so on.
Spring Boot includes support for the following embedded reactive web servers: Reactor Netty, Tomcat, Jetty, and Undertow. Most developers use the appropriate “Starter” to obtain a fully configured instance. By default, the embedded server listens for HTTP requests on port 8080.
the client instance is built using the WebClient.Builder bean auto-configured by Spring Boot
Developers can override the resource configuration for Jetty and Reactor Netty by providing a custom ReactorResourceFactory or JettyResourceFactory bean - this will be applied to both clients and servers.
You can learn more about the resource configuration on the client side in the WebClient Runtime section.
一、Vue的两种使用方式扩展核心包开发直接通过引入Vue.js,适用于简单页面或局部功能增强。优点:轻量,无需构建工具。缺点:难以管理复杂项目,缺少工程化支持。工程化开发使用VueCLI、Vite等工具创建项目,结合Webpack/Vite构建。支持单文件组件(.vue文件),结构清晰(`,,)。插件生态丰富(如VueRouter、Vuex、Pinia)。二、Vue实例的深入理解核心配置项 new
在数据库系统中存储过程是必不可少的利器,存储过程是预先编译好的为实现一个复杂功能的一段Sql语句集合。它的优点我就不多说了,说一下我碰到的问题吧。我在项目开发的过程中需要用存储过程来实现一个功能,其中涉及到判断一张表是否已经建立,没有建立就由存储过程来建立这张表。
CREATE OR REPLACE PROCEDURE TestProc
IS
fla
使用jsonp不能发起POST请求。
It is not possible to make a JSONP POST request.
JSONP works by creating a <script> tag that executes Javascript from a different domain; it is not pos
(一)Keepalived
(1)安装
# cd /usr/local/src
# wget http://www.keepalived.org/software/keepalived-1.2.15.tar.gz
# tar zxvf keepalived-1.2.15.tar.gz
# cd keepalived-1.2.15
# ./configure
# make &a