SpringBoot2

全局捕获异常

  • @ExpectionHandler 拦截异常
  • @ControllerAdvice 切面

案例

  1. 定义一个全局异常类
/**
 * 用于捕获全局的异常
 */
@ControllerAdvice   //控制器切面
public class GlobalExpectionHandler {

    @ExceptionHandler(RuntimeException.class)   //捕获运行时异常
    @ResponseBody //返回json
    public Map<String,Object> expectionHandler(){   //处理异常方法
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("errorCode","101");
        map.put("errorMsg","系统错误");
        return map;
    }
}
  1. APP中配置扫描包的范围,得包括expection包
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.tang.web")
public class App
{
    public static void main(String[] args)
    {
        //启动Springboot项目
        SpringApplication.run(App.class,args);
    }
}
  1. 算数异常捕获结果(int i= 10/0)
    {“errorCode”:“101”,“errorMsg”:“系统错误”}

Freemaker使用(相当于jsp)

  1. pom.xml中导入依赖
<!-- 引入freeMarker的依赖包. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
  1. 编写控制器,返回数据
  • 这里使用Controller

    @RestController用于写API,给移动客户端提供数据,一般是返回json数据
    @Contoller一般用于写后台(有页面)
    
@Controller
@RequestMapping("stu")
public class StudentController {

    @RequestMapping("list")
    public String list(Model model){
        model.addAttribute("username","tang");
        model.addAttribute("age",20);
        List<Student> stuList = new ArrayList<Student>();
        stuList.add(new Student(1001,"zhangsan","男"));
        stuList.add(new Student(1002,"lisi","男"));
        stuList.add(new Student(1003,"wangwu","男"));
        model.addAttribute("stuList",stuList);

        return "stu/list"; //找模板页面
    }
}
  1. 创建.ftl模板文件
  • 在resources包里创建templates文件夹
<body>
欢迎 ${username}
<#if (age < 17) >-小哥
<#elseif (age > 30) >大叔
<#else> 帅哥/美女
</#if>
登录
<br>
学生列表<br>
<table border="1">
    <tr>
        <td>ID</td>
        <td>名字</td>
        <td>性别</td>
    </tr>

    <#list stuList?sort_by("id")?reverse as stu>
        <tr>
            <td>${stu.id}</td>
            <td>${stu.username}</td>
            <td>${stu.gender}</td>
        </tr>
    </#list>
</table>
</body>

Springboot使用jsp,不常用

  1. 创建war maven工程
  2. 导入依赖
 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>
  <dependencies>
    <!-- SpringBoot 核心组件 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  1. 在resources文件夹创建application.properties配置文件
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp

server.port=8888
server.context-path=/test1
  1. 创建Controller
@Controller
@EnableAutoConfiguration
@RequestMapping("teacher")
public class TeacherController {

    @RequestMapping("list")
    public String list(){
        return "teacher/list";
    }

    public static void main(String[] args) {
        SpringApplication.run(TeacherController.class,args);
    }
}

5.在WEB-INF文件夹创建view以及其他文件,进行访问

  • 路径 http://localhost:8888/test1/teacher/list
  • 结果 aaa

Springboot数据库访问

使用jdbc

  1. 添加依赖
<!--JDBC -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <!--数据库驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--单元测试-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  1. application.properties新增配置
#数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/edu1
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  1. 创建Service
  • 创建IUserService接口
public interface IUserService {
    public void register(String username,String password);
}
  • 创建UserServiceImpl实现类
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void register(String username, String password) {

        String sql = "insert t_user (username,password) values (?,?)";
        jdbcTemplate.update(sql,username,password);
    }
}
  1. 在UserController中添加注册方法
 @Autowired
    private IUserService userService;
    @RequestMapping("register")
    @ResponseBody
    public String register(String username,String password){
        userService.register(username,password);
        return "success";
    }
  1. App启动中@ComponentScan扫描包中添加Service包
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.tang.web","com.tang.service"})
public class App
{
    public static void main( String[] args )
    {
        //启动Springboot项目
        SpringApplication.run(App.class,args);
    }
}

SpringBoot整合Mybatis

注解方式
  1. 导入依赖
<!--Spring boot 父依赖提供了依赖管理,之后申明其他的dependency的时候就不需要version了-->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>
  <dependencies>
    <!--Spring boot配置web的依赖-->
    <!--springweb核心组件-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--引入freeMarker的依赖-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>

    <!-- mybaties -->
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>1.1.1</version>
    </dependency>
    <!--数据库驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--单元测试-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
      </dependency>

  </dependencies>
  1. 数据库配置文件application.properties
  2. 注解形式Mapper
public interface UserMapper {

    @Insert("insert t_user (username,password) values (#{username},#{password})")
    public int save(@Param("username") String username ,@Param("password") String password);

    @Select("select * from t_user where username = #{username}")
    public User findByUsername(@Param("username") String username);
}
  1. Service接口和实现类
  • IUserService
public interface IUserService {
    public void register(String username,String password);
}
  • UserServiceImpl
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void register(String username, String password) {
        userMapper.save(username, password);
    }
}
  1. Controller
@Autowired
    private IUserService userService;
    @RequestMapping("register")
    @ResponseBody
    public String register(String username,String password){
        userService.register(username,password);
        return "success";
    }
xml方式
  1. 在Mapper包中创建xml形式的Mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tang.mapper.UserMapper" >
    <insert id="save">
        insert into t_user (username,password) values(#{0},#{1})
    </insert>

    <select id="findByUsername" resultType="com.tang.model.User" parameterType="string">
        select * from t_user where username = #{username,jdbcType=VARCHAR}
    </select>
</mapper>
  • 这里values后面#{}里面必须为0开始的数字
  • 如果要不写成0,1的形式,需要在接口方法添加@Param
public int save(@Param("username") String username ,@Param("password") String password);

public User findByUsername(String username);
  • #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。#{}可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
  • 表 示 拼 接 s q l 串 , 通 过 {}表示拼接sql串,通过 sql{}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, 可 以 接 收 简 单 类 型 值 或 p o j o 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值, pojoparameterType{}括号中只能是value
  1. 在pom添加resources使得能够扫描到xml文件中的SQL语句
 <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
  1. Service中实现findByUsername
public User findByUsername(String username);
@Override
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }
  1. Controller
@RequestMapping("find")
    @ResponseBody
    public User find(String username){
        return userService.findByUsername(username);
    }
  1. 运行结果
  • http://localhost:8080/user/find?username=tang
  • {“id”:1,“username”:“tang”,“password”:“1234”}

配置多个数据源

  • 一个工程操作两个数据库
  • 通过注解来配置数据源,以前在applicationContext.xml中配置数据源
  • 配置两个数据库
    application.properties
spring.datasource.test1.driverClassName=com.mysql.jdbc.Driver
spring.datasource.test1.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username=roota
spring.datasource.test1.password=123456

spring.datasource.test2.driverClassName=com.mysql.jdbc.Driver
spring.datasource.test2.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username=root
spring.datasource.test2.password=123456
  1. 创建datasource包,写两个数据源配置

DataSource01

@Configuration//注解到springboot容器中
@MapperScan(basePackages="com.gyf.test1.mapper",sqlSessionFactoryRef="test1SqlSessionFactory")
public class DataSource01 {

    /**
     * @return 返回test1数据库的数据源
     */
    @Bean(name="test1DataSource")
    @Primary//主数据源
    @ConfigurationProperties(prefix="spring.datasource.test1")
    public DataSource dateSource(){
        return DataSourceBuilder.create().build();
    }

    /**
     * @return 返回test1数据库的会话工厂
     */
    @Bean(name = "test1SqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("test1DataSource") DataSource ds) throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);

        return bean.getObject();
    }

    /**
     * @return 返回test1数据库的事务
     */
    @Bean(name = "test1TransactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

DataSource02

@Configuration//注解到springboot容器中
@MapperScan(basePackages="com.gyf.test2.mapper",sqlSessionFactoryRef="test2SqlSessionFactory")
public class DataSource02 {

    /**
     * @return 返回test2数据库的数据源
     */
    @Bean(name="test2DataSource")
    @ConfigurationProperties(prefix="spring.datasource.test2")
    public DataSource dateSource(){
        return DataSourceBuilder.create().build();
    }

    /**
     * @return 返回test2数据库的会话工厂
     */
    @Bean(name = "test2SqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("test2DataSource") DataSource ds) throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);

        return bean.getObject();
    }

    /**
     * @return 返回test2数据库的事务
     */
    @Bean(name = "test2TransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
  • 只能有一个主数据源
  1. 分别在test1和test2包中编写service和mapper
  2. Controller中@Autowired两个Service并在方法中同时调用两个Service层方法
  3. App中@ComponentScan中添加datasource包进行扫描

多数据源存在的问题

@Service
@Transactional
public class UserServiceImpl{

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CustomerMapper customerMapper;
    public void register(String username, String password) {
        customerMapper.save(username,"1");
        int i = 10/0;
        userMapper.save(username,password);
    }

}

test1中的service发生错误时无法对test2操作的事务进行回滚

SpringBoot的多事务管理

  • 使用spingboot+jta+atomikos分布式事务管理解决上面的问题
  1. 添加jta事务依赖
<!--jta事务依赖-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jta-atomikos</artifactId>
      <version>2.1.5.RELEASE</version>
    </dependency>
  1. 修改application.properties
# Mysql 1
mysql.datasource.test1.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
mysql.datasource.test1.username = root
mysql.datasource.test1.password = 123456

mysql.datasource.test1.minPoolSize = 3
mysql.datasource.test1.maxPoolSize = 25
mysql.datasource.test1.maxLifetime = 20000
mysql.datasource.test1.borrowConnectionTimeout = 30
mysql.datasource.test1.loginTimeout = 30
mysql.datasource.test1.maintenanceInterval = 60
mysql.datasource.test1.maxIdleTime = 60

mysql.datasource.test1.testQuery = select 1
# Mysql 2
mysql.datasource.test2.url =jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
mysql.datasource.test2.username =root
mysql.datasource.test2.password =123456
mysql.datasource.test2.minPoolSize = 3
mysql.datasource.test2.maxPoolSize = 25
mysql.datasource.test2.maxLifetime = 20000
mysql.datasource.test2.borrowConnectionTimeout = 30
mysql.datasource.test2.loginTimeout = 30
mysql.datasource.test2.maintenanceInterval = 60
mysql.datasource.test2.maxIdleTime = 60
mysql.datasource.test2.testQuery = select 1
  1. 创建dbconfig包,添加两个配置模型
  • 注意:要生成两个类的getter/setter方法
@ConfigurationProperties("mysql.datasource.test1")
public class DBConfig1 {
    private String url;
    private String username;
    private String password;
    private int minPoolSize;
    private int maxPoolSize;
    private int maxLifetime;
    private int borrowConnectionTimeout;
    private int loginTimeout;
    private int maintenanceInterval;
    private int maxIdleTime;
    private String testQuery;
}
@ConfigurationProperties("mysql.datasource.test2")
public class DBConfig2 {
    private String url;
    private String username;
    private String password;
    private int minPoolSize;
    private int maxPoolSize;
    private int maxLifetime;
    private int borrowConnectionTimeout;
    private int loginTimeout;
    private int maintenanceInterval;
    private int maxIdleTime;
    private String testQuery;
}
  1. 重新修改datasource包里DataSource1和DataSource2的代码
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.gyf.dbconfig.DBConfig1;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;

@Configuration//注解到springboot容器中
@MapperScan(basePackages="com.gyf.test1.mapper",sqlSessionFactoryRef="test1SqlSessionFactory")
public class DataSource01 {

    // 配置数据源
    @Primary
    @Bean(name = "test1DataSource")
    public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl(testConfig.getUrl());
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
        mysqlXaDataSource.setPassword(testConfig.getPassword());
        mysqlXaDataSource.setUser(testConfig.getUsername());
        mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("test1DataSource");

        xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
        xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
        xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
        xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
        xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
        xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
        xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
        xaDataSource.setTestQuery(testConfig.getTestQuery());
        return xaDataSource;
    }

    @Bean(name = "test1SqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }

    @Bean(name = "test1SqlSessionTemplate")
    public SqlSessionTemplate testSqlSessionTemplate(
            @Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration//注解到springboot容器中
@MapperScan(basePackages="com.gyf.test2.mapper",sqlSessionFactoryRef="test2SqlSessionFactory")
public class DataSource02 {

    /**
     * @return 返回test2数据库的数据源
     */
    @Bean(name="test2DataSource")
    @ConfigurationProperties(prefix="spring.datasource.test2")
    public DataSource dateSource(){
        return DataSourceBuilder.create().build();
    }

    /**
     * @return 返回test2数据库的会话工厂
     */
    @Bean(name = "test2SqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("test2DataSource") DataSource ds) throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);

        return bean.getObject();
    }

    /**
     * @return 返回test2数据库的事务
     */
    @Bean(name = "test2TransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * @return 返回test2数据库的会话模版
     */
    @Bean(name = "test2SqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(
            @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
  1. 在App中追加配置
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.gyf.datasource","com.gyf.web","com.gyf.test1.service","com.gyf.test2.service"})
@EnableConfigurationProperties(value= {DBConfig1.class, DBConfig2.class})
public class App
{
    public static void main( String[] args )
    {
        //启动springboot项目
        SpringApplication.run(App.class,args);
    }
}
  • REST Client工具启动方式: Tools->HTTP Client->Test Restful Web Service

    IDEA打开文件快捷键:Ctrl+Shift+N

SpringBoot整合Log4j

  1. 在resources包中创建log4j.properties
log4j.rootLogger=INFO,Console,File
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c - %L]%m%n

log4j.appender.File = org.apache.log4j.RollingFileAppender
log4j.appender.File.File = D:/test/logs/info/info.log
log4j.appender.File.MaxFileSize = 10MB

log4j.appender.File.Threshold = ALL
log4j.appender.File.layout = org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c - %L]%m%n
  1. pom.xml中进行配置
  • 去除springboot的logging,添加log4j,因为自带的logging没效果
 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
<!--重新导入log4j-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j</artifactId>
      <version>1.3.8.RELEASE</version>
    </dependency>
  1. 在Controller中添加logger,并调用logger.info方法进行信息展示,通过配置文件可以生成目录的log包
@RestController //声明Rest风格的控制器
//@EnableAutoConfiguration //自动配置,相当于写了spring的配置文件
@RequestMapping("user")
public class UserController {
    @Autowired
    private UserServiceImpl userService;

    Logger logger = Logger.getLogger(UserController.class);
    @Autowired
    private CustomerServiceImpl customerService;

    @RequestMapping("register")
    @ResponseBody
    public String register(String username,String password){
        //记录客户端请求参数
        logger.info("=====" + "username" + username + " password" + password);
        //把数据保存到test1数据库
        userService.register(username,password);
        //把数据保存到test2数据库
        customerService.save(username,"120");
        return "success";
    }
}
  1. 结果

    打开:D:/test/logs/info/info.log

    结果:[INFO] [2019-05-23 13:39:01][com.gyf.web.controller.UserController - 30]=====usernamehu password1234

使用AOP统一处理Web请求日志

  • 使用切面拦截所有控制器的方法,统一来记录
  1. 导入依赖
    <!-- Aspectj Weaver切面 -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.2</version>
    </dependency>
  1. 创建aspect包,编写切面类
package com.gyf.aspect;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Aspect
@Component
public class WebLogAspect {
    private Logger logger = Logger.getLogger(getClass());

    @Pointcut("execution(public * com.gyf.web.controller..*.*(..))")
    public void webLog() {

    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 记录下请求内容
        logger.info("---------------request----------------");
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        Enumeration<String> enu = request.getParameterNames();
        while (enu.hasMoreElements()) {
            String name = (String) enu.nextElement();
            logger.info("name:" + name + "value" + request.getParameter(name));
        }
    }
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        logger.info("---------------response----------------");
        // 处理完请求,返回内容
        logger.info("RESPONSE : " + ret);
    }
}
  1. Controller中将之前log4j的调用方法去掉,使用Aop切面的方式
@RestController //声明Rest风格的控制器
//@EnableAutoConfiguration //自动配置,相当于写了spring的配置文件
@RequestMapping("user")
public class UserController {
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private CustomerServiceImpl customerService;

    @RequestMapping("register")
    @ResponseBody
    public String register(String username,String password){
        //把数据保存到test1数据库
        userService.register(username,password);
        return "success";
    }

    @RequestMapping("login")
    @ResponseBody
    public String login(String username,String password){
        return "success";
    }
}
  1. 访问

URL:http://localhost:8080/user/login?username=yi&password=123

结果:Success

日志打印

[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 31]---------------request----------------
[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 32]URL : http://localhost:8080/user/login
[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 33]HTTP_METHOD : GET
[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 34]IP : 0:0:0:0:0:0:0:1
[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 38]name:usernamevalueyi
[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 38]name:passwordvalue123
[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 43]---------------response----------------
[INFO] [2019-05-23 14:37:49][com.gyf.aspect.WebLogAspect - 45]RESPONSE : success
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值