Spring Boot 极简系列 三:特征二

日志

  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的基本运用特点,都在这里了。还有其它的日志、模板等等。期待中。。。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值