日志
spring boot 对于所有的内部日志使用commons logging,但是保留了底层开放日志实现。默认的配置被Java Util Logging、Log4J2 和Logback提供。在每一个情况下,日志被默认使用控制台输出,也可以选择指定文件输出日志。
日志格式
默认的日志输出如下:
输入有以下几项:
1、日期和时间,毫秒的精度和容易排序的。
2、日志级别,ERROR,WARN,INFO,DEBUG, 或者TRACE。这里是INFO级别
3、进程ID,上面输出的进程ID是16450
4、--- 这个线是区别实际日志的分隔符。
5、线程名字。上面的输出线程,开始是main线程,然后经过了ost-startStop-1线程,nio-8080-exec-1,Thread-3。
6、日志名字。
7、日志信息。
控制台输出颜色:根据等级不同输出不同
级别 | 颜色 |
FATAL | 红色 |
ERROR | 红色 |
WARN | 黄色 |
INFO | 绿色 |
DEBUG | 绿色 |
TRACE | 绿色 |
文件输出
默认的spring boot日志仅仅控制台输出,不会输出日志文件。如果你想控制台输出之外还想日志文件输出,那么你需要设置logging.file或者logging.path属性(例如在你的application.properties中或者application.yml中)。
例如在application.properties中:
logging.file=springboot1.output
那么以后的控制台输出的日志也会在springboot1.output中。
当日志文件达到10Mb的时候,会循环输出,就像控制台ERROR-level,WARN-level, 和INFO-level默认的日志记录一样。日志大小的限制也可以被logging.file.max-size这个属性来设置。以前的被循环的文档被无限期的存档,除非logging.file.max-history属性被设置。
自定义日志配置
通过设置org.springframework.boot.logging.LoggingSystem系统属性,你可以强制spring boot使用某一个日志系统。输出的值的生成接口会被你设置的系统来实现。
系统设置值:
日志系统 | 说明 |
Logback | logback-spring.xml,logback-spring.groovy, logback.xml, 或者logback.groovy |
Log4j2 | log4j2-spring.xml或者log4j2.xm |
JDK (Java Util Logging) | logging.properties |
为了自定义,其它的属性设置也是可以的(比如日志文件):
spring 环境 | 说明 |
logging.exception-conversion-word | 日志异常时转换字被使用 |
logging.file | 日志输出文件 |
logging.file.max-size | 最大的日志文件大小设置(仅仅支持默认的logback设置) |
logging.file.max-history | 支持最大的日志打包数量(仅仅支持默认的logback设置) |
logging.path | 日志输出文件 |
logging.pattern.console | 在控制台使用的日志模式(仅仅支持默认的logback设置) |
logging.pattern.dateformat | 日期格式的附属模式(仅仅支持默认的logback设置) |
logging.pattern.file | 日志模式被用的文件(仅仅支持默认的logback设置) |
logging.pattern.level | 渲染日志等级的时,被使用的模式等级 |
PID | 进程数 |
使用:在application.properties中
logging.file=springboot1.output
logging.file.max-size=20MB
org.springframework.boot.logging.LoggingSystem=Logback
web应用
Spring boot 是非常适合web应用开发的。你可以创建一个独立的http服务器程序,通过使用嵌入Tomcat、Jetty,、Undertow, 或者 Netty。大部分的web应用使用spring-boot-starter-web模块来开始创建和快速的启动应用。你也可以选择性的使用spring-boot-starter-webflux模块来创建可交互式的web应用。
Spring MVC框架
Spring MVC 是一个丰富的"model -view-controller"框架。Spring MVC可以使用创建@RestController和@Controller的bean类来处理到来的HTTP请求。通过使用@RequestMapping注解,在你的Controller中方法被映射到HTTP上。
例如下面使用@RestController,服务器返回JSON数据。
package com.xiaoyunchengzhu.spring_application.controller;
import com.xiaoyunchengzhu.spring_application.bean.Good;
import com.xiaoyunchengzhu.spring_application.bean.Message;
import com.xiaoyunchengzhu.spring_application.bean.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Test {
@Autowired
User user;
@Autowired
Good good;
@Autowired
Message message;
@RequestMapping("/getUser")
public User getUser(){
return user;
}
@RequestMapping("/getGood")
public Good getGood(){
return good;
}
@RequestMapping("/getMessage")
public String getMessage(){
return message.getMessage();
}
}
Spring MVC自动配置
Spring boot 为Spring MVC提供的自动配置对于大部分项目,效果都是非常好的。
自动配置特点:
1、ContentNegotiatingViewResolver和BeanNameViewResolver bean类
2、支持服务静态资源
3、Converter,GenericConverter, 和Formatter的自动注册
4、支持HTTP信息的转换。HttpMessageConverters
5、支持信息码的解析转换。MessageCodesResolver
6、静态index.html支持
7、自动Favicon支持。
8、自动使用ConfigurableWebBindingInitializer
如果你想保持Spring boot MVC的特点,又想使用额外的MVC的配置(interceptors, formatters, view controllers, 和 other 其它特点),你可以添加你自己的WebMvcConfigurer类型的@Configuration类,并且不使用@EnableWebMvc.如果你希望提供自定义的RequestMappingHandlerMapping、RequestMappingHandlerAdapter、 或者ExceptionHandlerExceptionResolver的实例,你可以声明一个WebMvcRegistrationsAdapter实例来提供那样的组件。
HttpMessageConverters
Spring MVC适用HttpMessageConverter接口来转换HTTP请求和回复。合理的默认值被包含在框架中,比如类可以被自动的转换成JSON或者XML格式数据,同样的String字符串编码方式为UTF-8。
如果你想添加或者自定义转换,你可以适用Spring boot 的HttpMessageConverters类,
例如:目前默认的HTTP回复的对象格式为JSON,那么我们改为XML格式
package com.xiaoyunchengzhu.spring_application.config;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
@Configuration
public class Myconfig {
@Bean
public HttpMessageConverters customConverters(){
HttpMessageConverter<?> xmlHttpMessageConverter = new MappingJackson2XmlHttpMessageConverter();
return new HttpMessageConverters(xmlHttpMessageConverter);
}
}
默认没有的库要引入进来pom文件中。
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.6</version>
</dependency>
执行,请求原来的对象返回的接口,就会看到原来的对象返回JSON格式就会变成XML格式
静态资源内容
默认的静态内容来自类路径叫做/static (/public或者/resources或者/META-INF/resources)的目录或者来自于ServletContext的根目录。它使用来自Spring MVC的ResourceHttpRequestHandler,所以你可以定义它的行为,通过添加你自己的WebMvcConfigurer或者重写addResourceHandlers方法。
默认情况下,资源被映射到 /**,但是你可以用spring.mvc.static-path-pattern属性来调整。例如:
spring.mvc.static-path-pattern=/resources/**
你也可以定义静态资源的位置,需要通过spring.resources.static-locations属性。Servlet跟目录/有也会自动添加作为目录位置。
除了标准的静态资源路径之外,还有一个特殊的情况专门为了web的jar包内容,如果被打包成web的jar格式包,那么任何携带者/webjars/**的资源都会被提供。
注意:如果你的应用被打包成jar包的形式,那么不要使用src/main/webapp目录,尽管这个目录是最通用标准的,它使用在war包中非常的适用。并且如果你生成一个jar包,那么它会被大部分的构建工具默默的忽略。
欢迎页
Spring boot提供了静态和模板的欢迎页,首先会去静态内容路径中查找index.html的文件,如果没有发现,那么会找index的模板的文件,如果都没发现,那么会使用系统定义的欢迎页。
例如:
欢迎页放到了静态内容路径,那么请求默认地址,会访问这个index.html
自定义Favicon
Spring boot会在静态内容路径里和根目录寻找favicon.ico,如果找到,则会自动使用作为应用的图标。应用默认的favicon就是那个绿色的小叶子。
我们改变一下:
自定义的favicon.ico,放到目录,resources/static下,同时spring.mvc.favicon.enabled=false配置到application.properties,或者application.yml的形式配置。
图标就从小叶子变为自己配置的。
如果发现没有改变图标,那么刷新一下浏览器,还有缓存清理一下。再次打开。试试。
路径匹配和内容转让
Spring MVC可以通过查看请求路径来映射处理HTTP请求,和匹配它到定义映射的应用程序中。Spring 默认选择禁用后缀模式匹配,意味着例如请求GET /projects/spring-boot.json不会匹配@GetMapping("/projects/spring-boot")映射。这被认为是Spring MVC最好的应用适用。这是对没有发送 Accept请求头部的客户端是非常有用的,我们必须确认向客户端发送正确的内容类型,如此,内容的传输更可靠。
还有另一种方式,代替适用后缀匹配,通过适用查询参数的方式来请求匹配,例如"GET /projects/spring-boot?format=json"
会映射到@GetMapping("/projects/spring-boot")去处理。
这里其实就是Spring MVC处理如何去定向HTTP请求处理。例如Controller中不同的请求路径映射到不同的被@RequestMapping注解的方法。
ConfigurableWebBindingInitializer
Spring MVC 使用WebBindingInitializer来初始化WebDataBinder对于特殊的请求。如果你创建了自己的ConfigurableWebBindingInitializer@Bean,Spring boot会自动使用它配置Spring MVC。
例子如下:web数据绑定问题。通常http客户端所传入的参数,都是字符类型,那么如何转换成对象的形式来处理参数。
这里以时间转换字符串为例:自己创建了实现WebBindingInitializer,并初始化添加注册。
package com.xiaoyunchengzhu.spring_application.config;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@Component
public class MyWebBindInitializer implements WebBindingInitializer {
@Override
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.registerCustomEditor(Timestamp.class,"date",new PropertyEditorSupport(){
@Override
public void setAsText(String text) throws IllegalArgumentException {
super.setAsText(text);
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Timestamp timestamp = new Timestamp(sdf.parse(text).getTime());
this.setValue(timestamp);
} catch (ParseException var3) {
throw new IllegalArgumentException("Could not parse date: " + var3.getMessage(), var3);
}
}
@Override
public String getAsText() {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format((Timestamp)this.getValue());
}
});
}
}
在Controller中:
@RequestMapping(value = "/getDate",method = RequestMethod.GET)
public Timestamp getDate(@RequestParam(required = false) Timestamp date){
if (date!=null) {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(date));
}
return date;
}
重新打包执行后:
浏览器端: 测试打印console端:
那么我们可以自由的自定义格式的数据转换传入的参数对象了。
模板引擎
除了REST的WEB服务外,你还可以使用Spring MVC开发动态的html内容。Spring MVC支持多种模板技术,包括g Thymeleaf, FreeMarker, 和 JSPs。如果可能,尽量避免使用JSP。
当你使用这些默认配置的模板引擎的时候,你的模板自动的从src/main/resources/templates目录下读取。
例如使用Thymeleaf模板:
Controller代码:
package com.xiaoyunchengzhu.spring_application.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("html")
public class HtmlTestController {
@RequestMapping("/userInfo")
public String getUserInfo(Model model){
model.addAttribute("name","spring boot ");
model.addAttribute("age",26);
return "userInfo";
}
}
在src/main/resources/templates目录下创建userInfo.html文件:
<html xmlns:th="http://www.thymeleaf.org">
<header>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<title>登录</title>
</header>
<body>
<p th:text="'名字: ' + ${name}" ></p>
<p th:text="'年龄:' +${age}"></p>
</body>
</html>
执行之后,访问html/userInfo路径。:
错误处理
默认情况下,Spring boot提供一个/error的映射来合理的处理所有的错误,并且在servlet的容器中被注册为全局错误页。对于机器客户端,它提供一个json的返回错误内容,包括http状态,异常信息。对于浏览器,这是一个“whitelabel”页面视图,它渲染了一些数据在html的格式中。为了完全替换默认的错误页,你可以实现ErrorController并且注册一个被定义的Bean,和一个ErrorAttributes的bean,使用现有的机制,来替换内容。
默认的,我们的http请求返回的错误如下:
那么我们通过实现ErrorController来替换这个默认的内容,通常我们会用自定义的Json格式,表示一个error字段,和error码。
那么我们创建一个通用的错误model:
package com.xiaoyunchengzhu.spring_application.bean;
import java.sql.Timestamp;
public class ErrorMessage {
private String errorMessage;
private String code;
private Integer status;
private Timestamp date;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public void setDate(Timestamp date) {
this.date = date;
}
public Timestamp getDate() {
return date;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getStatus() {
return status;
}
}
ErrorController的实现:
package com.xiaoyunchengzhu.spring_application.controller;
import com.xiaoyunchengzhu.spring_application.bean.ErrorMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
@RestController
public class ErrorTestController implements ErrorController {
@Autowired
ErrorAttributes errorAttributes;
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping("/error")
public ErrorMessage getError(HttpServletRequest httpServletRequest){
ErrorMessage errorMessage=new ErrorMessage();
ServletWebRequest servletWebRequest = new ServletWebRequest(httpServletRequest);
Map<String, Object> errorAttributes = this.errorAttributes.getErrorAttributes(servletWebRequest, true);
errorMessage.setErrorMessage((String) errorAttributes.get("message"));
errorMessage.setDate(new Timestamp(new Date().getTime()));
errorMessage.setStatus((Integer) errorAttributes.get("status"));
errorMessage.setCode("104");
return errorMessage;
}
}
我们返回的是一个对象,我们这里默认json对象。
那么再次启动应用。访问错误页面的时候:
结果就是我们预期的自定义的错误格式。那么以后,就可以统一处理返回,无论是error的页面还是正确的返回值。
另外,还可以自定义HTML的error页面,无论是模板的动态页面还是静态页面。可以相关的搜索学习,这里省略介绍。
跨域支持
在4.2版本,Spring MVC支持跨域资源访问。使用@CrossOrigin注解Controller的方法跨域配置,不需要任何其它的特殊配置。
全局的跨域配置也可以被定义,通过注册一个WebMvcConfigurer bean 添加自定义的addCorsMappings方法。
如下:
@Configuration
public class Myconfig{
@Bean
public WebMvcConfigurer getCross(){
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/html/**");
}
};
}
}
ok,
Spring MVC的基本运用特点,都在这里了。还有其它的日志、模板等等。期待中。。。