Source code access method 1:
- Scan the qr code at the end of the article, pay attention to the public number [programming Daily], background reply [blog], you can get the source code
Source code access method two:
Front-end page source address: github.com/oneStarLR/m…
Jpa as a persistent layer source address: github.com/oneStarLR/m…
Mybatis as a persistent layer source address: github.com/oneStarLR/m…
Welcome to give encouragement to star
This article will be from the construction of SpringBoot framework, exception processing, log processing to tell the personal blog system background framework
First, build the SpringBoot framework
1. Use IDEA to quickly set up the SpringBoot framework
Use IDEA to create a new project, here is using JDK1.8, select the corresponding component, here select the following, click next, select save path to create a project (for SpringBoot not very clear partners can see my previous blog: SpringBoot framework introduction, SpringBoot framework principle analysis)
Once the project is created, the dependencies are automatically added based on the selected components. Of course, there are only some dependencies that we need, and some dependencies that we can add when we need them
2. Configure the YML file
Yml file is used for configuration. Therefore, change application.properties to Application. yml file and configure the SpringBoot project. When we are developing a project, the general development environment and deployment environment are different. To distinguish them, they can be reflected in the YML configuration file, so they are divided into application-dev.yml(development environment) and application-pro.yml(deployment environment). In order to let SpringBoot know which configuration file is used, the application. Yml configuration file should be specified, and the same configuration can be configured in application.
- Application. yml: Common configuration and indicates the current configuration file
- Application-dev. yml: development environment configuration file
- Application-pro. yml: deployment environment configuration file
application.yml
spring:
thymeleaf:
mode: HTML
profiles:
active: pro
mybatis:
type-aliases-package: com.star.entity
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
Copy the code
application-dev.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/myblog? useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: 111111
logging:
level:
root: info
com.star: debug
file: log/blog-dev.log
Copy the code
application-pro.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/myblog? useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&serverTimezone=GMT%2B8
username: root
password: 111111
logging:
level:
root: warn
com.star: info
file: log/blog-pro.log
Copy the code
Yml is configured with the Thymeleaf template, the active file of the current configuration, and the data persistence layer. The development environment and the deployment environment are configured with the database (the database user name and password of the two environments are usually different), and then the log file is configured. Log files can be generated in the specified folder.
You can override the SpringBoot default log configuration, customize the log size and name, and add logback-spring. XML to the resource folder to configure the following configuration:
<?xml version="1.0" encoding="UTF-8" ? >
<configuration>
<! -- Includes the default Spring Boot configuration for logback logs -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<! - rewrite the Spring framework org/Boot springframework/Boot/logging/logback/file - appender. XML configuration - >
<appender name="TIME_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i</fileNamePattern>
<! -- Keep history log for one month -->
<maxHistory>30</maxHistory>
<! -- Spring Boot by default, log files at 10M will be split.
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="TIME_FILE" />
</root>
</configuration>
<! -- Inherit the Spring Boot Logback Settings (you can use appliaction.yml or application.properties to set the logging.* property). Split log by date -->
Copy the code
3. Run
As this series of blogs is only about the development of the back end of the blog, the front end will not be discussed in detail. You can download the front end of the blog directly from GitHub (welcome star) : github.com/oneStarLR/m… Import the front page into the project, and make sure the directory is in the right place
At this point, the basic framework is set up and ready to run. You can see the logs printed under the dev and Pro configuration and the project automatically generates a log folder to store the dev and Pro log files.
Dev log print:
Pro log printing:
In order to see more information during development, use the dev configuration environment
Second, exception handling
In the page access, there will be some more common exceptions error information, such as path can not access 404 exception, server error 500 exception and their own definition of the error page and so on, SpringBoot framework provides a method to deal with the error page, here, we 404, 500, error exception page processing.
1. Define the error page
In the templates directory of the front-end page, there is the error folder. SpringBoot can find abnormal pages by the name of the folder and the name of the error file. Therefore, the file name must be fixed, and there are the following abnormal pages:
- 404.html
- 500.html
- error.html
To test this with controllers, create a new controller package under the com.star folder and create the IndexController controller as the home controller as follows:
package com.star.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/ * * *@Description: Home controller *@Date: Created in 21:01 2020/5/20
* @Author: ONESTAR
* @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
*/
@Controller
public class IndexController {
// Request the path through get
@GetMapping("/")
public String index(a){
return "index"; }}Copy the code
404 page test: you can enter http://localhost:8080/ in the browser, you can visit the homepage of the blog, you can change the path, such as adding an invalid suffix, after the visit, you find the jump to the 404 page written by myself
Int a = 9/0; int a = 9/0; (The denominator cannot be zero, so the server will have an error), then go to: http://localhost:8080/, find 500 page, this means that there is no problem (remember to comment out the error caused by 500).
2. Handle global exceptions
For 404 and 500 error pages, SpringBoot can find the corresponding file according to the name of the page, and the custom error we need to intercept, let the code when the problem redirects to our own defined error page, here we need to custom interceptor.
In com. Star folder under the new hander package, create ControllerExceptionHandler error page interceptors, by defining the class to intercept all exceptions, the code is as follows:
package com.star.controller.hander;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/ * * *@Description: Intercepting exception handling *@Date: Created in 21:40 2020/5/20
* @Author: ONESTAR
* @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
*/
@ControllerAdvice
public class ControllerExceptionHandler {
// Log the exception
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/ * * *@Description: Handles error messages *@Auther: ONESTAR
* @Date: 21:52 2020/5/20
* @Param: request: indicates the abnormal URL *@Param: e: abnormal parameter *@Return: Returns the error message page */
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHander(HttpServletRequest request, Exception e) throws Exception {
// Record exception information: requested URL, exception information
logger.error("Requst URL: {}, Exception: {}", request.getRequestURL(),e);
// Do not intercept when the status code is identified
if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) ! =null) {
throw e;
}
// Return the recorded exception information to the error page
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception", e);
mv.setViewName("error/error");
returnmv; }}Copy the code
Analysis:
- @controllerAdvice: intercepts all controllers with the @Controller annotation
- @ExceptionHandler Indicates the exception handling method
- ModelAndView: Returns a page information
- By intercepting the exception information, it is recorded in the log and returned to the error page
- Do not intercept when a status code is identified, for example, an exception cannot be found
3. If resources cannot be found, handle the exception
Create a NotFoundException class in the com.star folder.
package com.star;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/ * * *@Description: Custom exception *@Author: ONESTAR
* @Date: Created in 16:03 2020/3/25
* @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
public NotFoundException(a) {}public NotFoundException(String message) {
super(message);
}
public NotFoundException(String message, Throwable cause) {
super(message, cause); }}Copy the code
Analysis:
- Inheriting RuntimeException implements the constructor that inherits RuntimeException
- The @responseStatus (httpstatus.not_found) annotation indicates that the resource’s status code was not found
Three, log processing
AOP in SpringBoot for log processing, AOP can intercept in the form of section, log content recorded, here to record the following log information:
- To access the URL
- Visitor’S IP
- Method invoked when accessing
- Parameters passed when accessing
- What is returned when accessed
1. Add dependencies
Add AOP dependencies to POM.xml
<! --AOP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Copy the code
2. Section processing
Create a new aspect package under the com.star folder and create a LogAspect logging section class to handle the logs as follows:
package com.star.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/ * * *@Description: Log section processing *@Date: Created in 23:31 2020/5/21
* @Author: ONESTAR
* @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
*/
@Aspect
@Component
public class LogAspect {
// Obtain log information
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// Define the section, declaring log() as a section
@Pointcut("execution(* com.star.controller.*.*(..) )")
public void log(a) {}
// execute before cutting
@Before("log()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// Get the URL and IP address
String url = request.getRequestURL().toString();
String ip = request.getRemoteAddr();
// Get the request method
String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
// Get the request parameters
Object[] args = joinPoint.getArgs();
RequestLog requestLog = new RequestLog(url, ip, classMethod, args);
logger.info("Request : {}", requestLog);
}
// Execute after cutting
@After("log()")
public void doAfter(a) {
// logger.info("--------doAfter--------");
}
// Intercept after return
@AfterReturning(returning = "result",pointcut = "log()")
public void doAfterRuturn(Object result) {
logger.info("Result : {}", result);
}
// Encapsulate the request parameters
private class RequestLog {
private String url;
private String ip;
private String classMethod;
private Object[] args;
public RequestLog(String url, String ip, String classMethod, Object[] args) {
this.url = url;
this.ip = ip;
this.classMethod = classMethod;
this.args = args;
}
@Override
public String toString(a) {
return "{" +
"url='" + url + '\' ' +
", ip='" + ip + '\' ' +
", classMethod='" + classMethod + '\' ' +
", args=" + Arrays.toString(args) +
'} '; }}}Copy the code
Analysis:
- Aspect annotation: AOP Aspect role
- Component annotations: Enable Component scanning and use annotations to find objects to scan
- @Pointcut(“execution(* com.star.controller..(..) Log () is an execution plane. Log () is an execution plane. Log () is an execution plane
- RequestLog: Encapsulates the request parameters into an inner class
- Before the page (controller) is accessed, the requested URL, IP, called method, passed parameter, returned content is intercepted and logged
Run the project, visit http://localhost:8080/, and you can see the log information printed on the console, recording the REQUESTED URL, IP, called method, passed parameters, returned content, and entered into the log
At this point, with the front page, the framework is completed