以前开发一直用的是Spring MVC,最近有时间就来研究一下Spring Boot。先说一下感受:SpringBoot比较适合快速开发,和SpringMvc比较起来的优点我觉得有:
1.配置快,启动快。
2.不需要依赖额外的安装tomcat,只需要几个jar包就能运行。
3.配置热部署插件,效率更高。
这几天找了好多教程,终于自己搭建出来自己熟悉的一套开发组件,下面会逐渐把代码贴出来。如果不了解spring boot的话可以去百度搜索 springboot入门。
项目的整体结构图:
一、jar包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.oig.spring-boot</groupId>
<artifactId>spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<dependencies>
<!--spring切面aop依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<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>
<!-- Spring 权限控制 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<!-- c3p0连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>mchange-commons-java</artifactId>
<version>0.2.11</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<!-- 通用工具类 -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version><!--$NO-MVN-MAN-VER$-->
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk15on</artifactId>
<version>1.56</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version><!--$NO-MVN-MAN-VER$-->
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.12</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>com.oig.js</groupId>
<artifactId>nashorn</artifactId>
<version>1.0.1</version>
</dependency>
<!-- 解析XML -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- 用来处理常用的编码方法的工具类包,例如DES、SHA1、MD5、Base64等等 -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
<!-- commons -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 没有该配置,devtools 不生效 -->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
<!-- 指定最终生成jar包的文件名-->
<finalName>spring-boot</finalName>
</build>
</project>
二、mybatis配置
1.先是一个mybatis的一个常规配置,数据源改用了c3p0,
package com.oig.application;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class DatasourceConfiguration {
@Bean(name = "dataSource")
@Qualifier(value = "dataSource")
@Primary
@ConfigurationProperties(prefix = "c3p0")
public DataSource dataSource(){
return DataSourceBuilder.create().type(com.mchange.v2.c3p0.ComboPooledDataSource.class).build();
}
//创建SqlSessionFactory
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
sqlSessionFactoryBean.setTypeAliasesPackage("com.oig.entity");
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mybatis/*.xml"));//指定mapper文件所在目录
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:com/oig/dao/*.xml"));//指定mapper文件所在目录
sqlSessionFactoryBean.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));
// return sqlSessionFactoryBean.getObject();
return sqlSessionFactoryBean;
}
//创建事务管理器
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
2.为mybatis添加了PageHelper组件,所以在上面指定加载了mybatis-config.xml文件,文件位置在src/main/resources下,文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 打印查询语句 -->
<setting name="logImpl" value="LOG4J" />
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 将积极加载改为消息加载即按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--
plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
properties?, settings?,
typeAliases?, typeHandlers?,
objectFactory?,objectWrapperFactory?,
plugins?,
environments?, databaseIdProvider?, mappers?
-->
<plugins>
<!-- <plugin interceptor="com.oig.mybatis.CreatedDateInterceptor"></plugin> -->
<!-- <plugin interceptor="com.oig.mybatis.LastModifiedDateInterceptor"></plugin> -->
<!-- <plugin interceptor="com.oig.mybatis.IdGenerateInterceptor"></plugin> -->
<!-- <plugin interceptor="com.oig.mybatis.VersionInterceptor"></plugin> -->
<!-- <plugin interceptor="com.oig.mybatis.CreatedByInterceptor"></plugin> -->
<!-- <plugin interceptor="com.oig.mybatis.LastModifiedByInterceptor"></plugin> -->
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样-->
<property name="offsetAsPageNum" value="true"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true"/>
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
<property name="pageSizeZero" value="true"/>
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="false"/>
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params" value="pageNum=pageHelperStart;pageSize=pageHelperRows;"/>
<!-- 支持通过Mapper接口参数来传递分页参数 -->
<property name="supportMethodsArguments" value="false"/>
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="none"/>
</plugin>
</plugins>
</configuration>
3.配置mybatis通用插件,这是第三方提供的一个开源插件,为mybatis提供了一些通用的增删查改,非常有用。
@Bean
public MapperScannerConfigurer mapperScan(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.oig.dao");
Properties properties = new Properties();
properties.put("style", "normal");
properties.put("mappers", "tk.mybatis.mapper.common.BaseMapper");
// properties.put("mappers", "com.oig.mybatis.mapper.BaseMapper");
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}
三、logback配置,在src/main/resources下,创建logback-spring.xml,spring boot会自动读取。详细的介绍可以看这篇文章:https://blog.csdn.net/inke88/article/details/75007649
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<springProperty scope="context" name="appname" source="logback.appname"/>
<springProperty scope="context" name="logdir" source="logback.logdir"/>
<contextName>${appname}</contextName>
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>-->
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,
所以我们使用下面的策略,可以避免输出 Error 的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤 Error-->
<level>ERROR</level>
<!--匹配到就禁止-->
<onMatch>DENY</onMatch>
<!--没有匹配到就允许-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${logdir}/info.${appname}.log</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${logdir}/info.${appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--只保留最近90天的日志-->
<maxHistory>90</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<!--<totalSizeCap>1GB</totalSizeCap>-->
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
</encoder>
</appender>
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>Error</level>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${logdir}/error.${appname}.log</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${logdir}/error.${appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--只保留最近90天的日志-->
<maxHistory>90</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<!--<totalSizeCap>1GB</totalSizeCap>-->
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="fileInfoLog" />
<appender-ref ref="fileErrorLog" />
</root>
<!-- logback为java中的包 -->
<!--<logger name="com.dudu.controller"/>-->
<!--logback.LogbackDemo:类的全路径 -->
<!--<logger name="com.dudu.controller.LearnController" level="WARN" additivity="true">-->
<!--<appender-ref ref="console"/>-->
<!--</logger>-->
<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
<logger name="com.oig.dao" level="DEBUG"/>
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
<logger name="com.oig.dao" level="DEBUG"/>
</springProfile>
</configuration>
四、spring-security配置,详细介绍可以看这篇文章:https://blog.csdn.net/u012702547/article/details/54319508
package com.oig.application;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import com.oig.security.AuthenticationFaliueHandler;
import com.oig.security.AuthenticationSuccessHandler;
import com.oig.service.impl.UserDetailServiceImpl;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
// @Bean
// public DaoAuthenticationProvider daoAuthenticationProvider(){
// DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
// daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
// daoAuthenticationProvider.setUserDetailsService(userDetailsService());
// return daoAuthenticationProvider;
// }
@Bean
public UserDetailServiceImpl userDetailService(){
return new UserDetailServiceImpl();
}
@Bean
public SimpleUrlAuthenticationSuccessHandler authenticationSuccessHandler() {
AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler();
return authenticationSuccessHandler;
}
@Bean
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
return new AuthenticationFaliueHandler();
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailService());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
// http.formLogin()
// //设置默认登录成功跳转页面
// .loginPage("/login")
// .successHandler(authenticationSuccessHandler())
// .failureHandler(authenticationFailureHandler())
.defaultSuccessUrl("/index")
.failureUrl("/login?error=true")
// .permitAll()
// .and()
// //开启cookie保存用户数据
// .rememberMe().rememberMeCookieName("rememberMe")
// //设置cookie有效期
// .tokenValiditySeconds(60 * 60 * 24 * 7)
// //设置cookie的私钥
// .key("wann").useSecureCookie(true)
// .and()
// .logout()
// //默认注销行为为logout,可以通过下面的方式来修改
// .logoutUrl("/logout")
//设置注销成功后跳转页面,默认是跳转到登录页面
// .logoutSuccessUrl("/login")
// .invalidateHttpSession(true).clearAuthentication(true).deleteCookies("JSESSIONID","rememberMe")
// .permitAll()
// .and()
// .authorizeRequests()
// .anyRequest().authenticated();
// http
// //http.authorizeRequests()方法有多个子节点,每个macher按照他们的声明顺序执行
// .authorizeRequests()
// //我们指定任何用户都可以访问多个URL的模式。
// //任何用户都可以访问以"/resources/","/signup", 或者 "/about"开头的URL。
// .antMatchers("/resources/**", "/signup", "/about").permitAll()
//
// //以 "/admin/" 开头的URL只能让拥有 "ROLE_ADMIN"角色的用户访问。
// //请注意我们使用 hasRole 方法,没有使用 "ROLE_" 前缀。
// .antMatchers("/admin/**").hasRole("ADMIN")
//
// //任何以"/db/" 开头的URL需要同时具有 "ROLE_ADMIN" 和 "ROLE_DBA"权限的用户才可以访问。
// //和上面一样我们的 hasRole 方法也没有使用 "ROLE_" 前缀。
// .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
//
// //任何以"/db/" 开头的URL只需要拥有 "ROLE_ADMIN" 和 "ROLE_DBA"其中一个权限的用户才可以访问。
// //和上面一样我们的 hasRole 方法也没有使用 "ROLE_" 前缀。
// .antMatchers("/db/**").hasAnyRole("ADMIN", "DBA")
//
// //尚未匹配的任何URL都要求用户进行身份验证
// .anyRequest().authenticated()
// .and()
// // ...
// .formLogin().loginPage("/login").permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
}
五、freemarker配置:
package com.oig.application;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
@Configuration
public class FreemarkerConfigurattion {
@Bean
public CommandLineRunner customFreemarker(final FreeMarkerViewResolver resolver) {
return new CommandLineRunner() {
@Override
public void run(String... args) throws Exception {
//增加视图
resolver.setViewClass(MyFreemarkerView.class);
//添加自定义解析器
// Map<String,Object> map = resolver.getAttributesMap();
}
};
}
}
package com.oig.application;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
public class MyFreemarkerView extends FreeMarkerView{
@Override
protected void exposeHelpers(Map<String, Object> model, HttpServletRequest request) throws Exception {
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + path;
model.put("base", basePath);
super.exposeHelpers(model, request);
}
}
六、启动主程序:
package com.oig.application;
import java.util.Properties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import com.fasterxml.jackson.databind.ObjectMapper;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;
@EnableAutoConfiguration
@SpringBootApplication
@ComponentScan(basePackages={"com.oig"})//指定spring要扫描的包
//@ImportResource(locations = {"classpath:applicationContext.xml","classpath:applicationContext-mvc.xml"})
@EnableCaching
//@MapperScan("com.oig.dao")//指定mapper文件所在的包
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// @Bean
// public ObjectMapper objectMapper(){
// ObjectMapper mapper = new ObjectMapper();
// mapper.findAndRegisterModules();
// return mapper;
// }
@Bean
public MapperScannerConfigurer mapperScan(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.oig.dao");
Properties properties = new Properties();
properties.put("style", "normal");
properties.put("mappers", "tk.mybatis.mapper.common.BaseMapper");
// properties.put("mappers", "com.oig.mybatis.mapper.BaseMapper");
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}
}
七、配置文件application.properties:
#server
#访问的根路径
server.context-path=/sb
#端口号
server.port=81
#session失效时间
server.session-timeout=30
tomcat.uri-encoding=utf-8
#日志配置
logback.appname=sb
logback.logdir=E\:\\test
spring.profiles.active=dev
spring.http.converters.preferred-json-mapper=gson
spring.jackson.serialization=true
spring.jackson.deserialization=true
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
#datasource
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/数据库?useUnicode=true&characterEncoding=UTF-8
c3p0.user=用户名
c3p0.password=密码
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.minPoolSize=5
c3p0.maxPoolSize=100
c3p0.maxIdleTime=600
c3p0.acquireIncrement=5
c3p0.maxStatements=1000
c3p0.initialPoolSize=5
c3p0.idleConnectionTestPeriod=60
c3p0.acquireRetryAttempts=30
c3p0.acquireRetryDelay=1000
c3p0.breakAfterAcquireFailure=false
c3p0.testConnectionOnCheckout=false
# FREEMARKER (FreeMarkerAutoConfiguration)
spring.freemarker.allow-request-override=false
spring.freemarker.allow-session-override=false
spring.freemarker.cache=true
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.enabled=true
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=true
spring.freemarker.prefer-file-system-access=true
spring.freemarker.suffix=.ftl
spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.settings.template_update_delay=0
spring.freemarker.settings.default_encoding=UTF-8
spring.freemarker.settings.classic_compatible=true
spring.freemarker.order=1
八、遗留问题1:mybatis通用mapper在Spring boot项目中的兼容性有点问题,会报错,解决方法是在src/main/resources下建一个文件 META-INF/spring-devtools.properties,内容如下:
restart.include.companycommonlibs=tk/mybatis.*
九、遗留问题2:在配置完成后遇到一个问题,通过@ResponseBody 返回的内容不是json,而是xml格式。经过百度搜集问题发现,是多了这个jar包,请求的时候会根据header中的accept头信息去返回json还是xml,xml的优先级较高,把下面这个jar去掉就不会了。或者@RequestMapping中produces = MediaType.APPLICATION_JSON_UTF8_VALUE 也能解决,但是不想每个请求都这么写。这个注解是SpringBoot带出来的注解。
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.7</version>
</dependency>
最后附上源码:
https://github.com/li1296883752/sb_test