├── .gitignore ├── .travis.yml ├── Dockerfile ├── README.md ├── boot.sql ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── xwolf │ │ ├── BootApplication.java │ │ └── boot │ │ ├── annotation │ │ └── AvoidRepeatableCommit.java │ │ ├── api │ │ ├── ApiBaseController.java │ │ └── UserBaseController.java │ │ ├── aspect │ │ └── AvoidRepeatableCommitAspect.java │ │ ├── config │ │ ├── Constants.java │ │ ├── DataSourceConfig.java │ │ ├── FilterConfig.java │ │ ├── InterceptorConfig.java │ │ └── SwaggerConfig.java │ │ ├── controller │ │ ├── ApiController.java │ │ ├── ErrorController.java │ │ └── UserController.java │ │ ├── dao │ │ └── IUserDao.java │ │ ├── entity │ │ └── User.java │ │ ├── interceptor │ │ ├── CsrfInterceptor.java │ │ ├── ErrorInterceptor.java │ │ ├── XSSFilter.java │ │ └── XSSHttpServletRequestWrapper.java │ │ ├── service │ │ ├── IUserService.java │ │ └── impl │ │ │ └── UserServiceImpl.java │ │ └── utils │ │ ├── IPUtil.java │ │ ├── StringUtils.java │ │ └── UUIDUtil.java └── resources │ ├── application.yml │ ├── logback.xml │ ├── mapper │ └── UserMapper.xml │ ├── mybatis.xml │ └── templates │ ├── 302.html │ ├── 400.html │ ├── 404.html │ └── 500.html └── test └── java └── com └── xwolf └── BootApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM java:8 3 | 4 | MAINTAINER xwolf 5 | 6 | ENV MIN_HEAP 512m 7 | ENV MAX_HEAP 2048m 8 | 9 | EXPOSE 8082 10 | 11 | RUN mkdir /opt/jars 12 | WORKDIR /opt/jars 13 | 14 | 15 | ENV MODULE boot 16 | ENV MODULE_VERSION 0.0.1-SNAPSHOT 17 | ADD ./${MODULE}-${MODULE_VERSION}.jar /opt/jars 18 | 19 | CMD java -jar -Xms${MIN_HEAP} -Xmx${MAX_HEAP} \ 20 | ${MODULE}-${MODULE_VERSION}.jar 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # boot 2 | >* Spring Boot 整合MyBatis 3 | >* 数据源Druid 监控 4 | >* PageHelper分页 5 | >* Hibernate validator 集成 6 | >* jackson 日期时间格式化 7 | >* swagger2 api管理 8 | >* 自定义Filter,避免XSS攻击和SQL注入攻击 9 | >* 自定义AOP配合redis解决重复提交问题 10 | >* 自定义拦截器,拦截referer来避免CSRF攻击 11 | >* 自定义拦截器,集成thymeleaf根据不同的响应状态码跳转不同的页面 12 | 13 | # docker集成 14 | 15 | 执行下面命令构建镜像 16 | 17 | ```bash 18 | mvn package docker:build 19 | ``` 20 | -------------------------------------------------------------------------------- /boot.sql: -------------------------------------------------------------------------------- 1 | 2 | /*用户表*/ 3 | CREATE TABLE `user` ( 4 | `uid` int(10) NOT NULL AUTO_INCREMENT, 5 | `uname` varchar(255) DEFAULT NULL, 6 | `birth` date DEFAULT NULL, 7 | KEY `uid` (`uid`) 8 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 9 | 10 | 11 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.xwolf 7 | boot 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | boot 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.9.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | xwolf 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-aop 33 | 34 | 35 | org.mybatis.spring.boot 36 | mybatis-spring-boot-starter 37 | 1.2.0 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-web 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-data-redis 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-thymeleaf 59 | 60 | 61 | 62 | 63 | net.sourceforge.nekohtml 64 | nekohtml 65 | 1.9.17 66 | 67 | 68 | 69 | org.apache.commons 70 | commons-lang3 71 | 3.7 72 | 73 | 74 | 75 | mysql 76 | mysql-connector-java 77 | 78 | 79 | 80 | 81 | com.alibaba 82 | druid 83 | 1.0.27 84 | 85 | 86 | 87 | 88 | com.alibaba 89 | fastjson 90 | 1.2.31 91 | 92 | 93 | org.projectlombok 94 | lombok 95 | 96 | 97 | com.google.guava 98 | guava 99 | 20.0 100 | 101 | 102 | com.github.pagehelper 103 | pagehelper 104 | 4.2.1 105 | 106 | 107 | 108 | io.springfox 109 | springfox-swagger2 110 | 2.6.1 111 | 112 | 113 | io.springfox 114 | springfox-swagger-ui 115 | 2.6.1 116 | 117 | 118 | 119 | 120 | 121 | 122 | org.springframework.boot 123 | spring-boot-maven-plugin 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-compiler-plugin 129 | 130 | 1.8 131 | 1.8 132 | 133 | 134 | 135 | 136 | 137 | com.spotify 138 | docker-maven-plugin 139 | 1.2.0 140 | 141 | ${docker.image.prefix}/${project.artifactId} 142 | 143 | . 144 | 145 | 146 | / 147 | ${project.build.directory} 148 | ${project.build.finalName}.jar 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/BootApplication.java: -------------------------------------------------------------------------------- 1 | package com.xwolf; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @MapperScan("com.xwolf.boot.dao") 9 | public class BootApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(BootApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/annotation/AvoidRepeatableCommit.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 避免重复提交 7 | * @author xwolf 8 | * @version 1.0 9 | * @since 1.8 10 | */ 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface AvoidRepeatableCommit { 14 | 15 | /** 16 | * 指定时间内不可重复提交,单位毫秒 17 | * @return 18 | */ 19 | long timeout() default 30000 ; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/api/ApiBaseController.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.api; 2 | 3 | import com.xwolf.boot.entity.User; 4 | import io.swagger.annotations.ApiImplicitParam; 5 | import io.swagger.annotations.ApiImplicitParams; 6 | import io.swagger.annotations.ApiOperation; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * [Swagger解耦] 14 | */ 15 | public interface ApiBaseController { 16 | 17 | @ApiOperation(value="获取用户列表", notes="") 18 | List getUserList(); 19 | 20 | @ApiOperation(value="创建用户", notes="根据User对象创建用户") 21 | @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User") 22 | String postUser(@RequestBody User user); 23 | 24 | @ApiOperation(value="获取用户详细信息", notes="根据url的id来获取用户详细信息") 25 | @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Integer") 26 | User getUser(@PathVariable Integer id); 27 | 28 | @ApiOperation(value="更新用户详细信息", notes="根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息") 29 | @ApiImplicitParams({ 30 | @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Integer"), 31 | @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User") 32 | }) 33 | String putUser(@PathVariable Integer id, @RequestBody User user); 34 | 35 | @ApiOperation(value="删除用户", notes="根据url的id来指定删除对象") 36 | @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Integer") 37 | String deleteUser(@PathVariable Integer id); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/api/UserBaseController.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.api; 2 | 3 | import com.xwolf.boot.entity.User; 4 | import io.swagger.annotations.ApiOperation; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | 7 | import javax.validation.Valid; 8 | import java.util.List; 9 | 10 | /** 11 | * @author wolf 12 | */ 13 | 14 | public interface UserBaseController { 15 | 16 | /** 17 | * 添加用户 18 | * @param user 19 | * @return 20 | */ 21 | @ApiOperation(value = "添加用户") 22 | String insert(@Valid User user); 23 | 24 | /** 25 | * 获取用户列表 26 | * @param start 27 | * @param size 28 | * @return 29 | */ 30 | @ApiOperation(value = "获取用户列表") 31 | List getUserList(@PathVariable("start")int start, @PathVariable("size")int size); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/aspect/AvoidRepeatableCommitAspect.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.aspect; 2 | 3 | import com.xwolf.boot.annotation.AvoidRepeatableCommit; 4 | import com.xwolf.boot.config.Constants; 5 | import com.xwolf.boot.utils.IPUtil; 6 | import com.xwolf.boot.utils.StringUtils; 7 | import com.xwolf.boot.utils.UUIDUtil; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.aspectj.lang.ProceedingJoinPoint; 10 | import org.aspectj.lang.annotation.Around; 11 | import org.aspectj.lang.annotation.Aspect; 12 | import org.aspectj.lang.reflect.MethodSignature; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.core.annotation.Order; 15 | import org.springframework.data.redis.core.RedisTemplate; 16 | import org.springframework.stereotype.Component; 17 | import org.springframework.web.context.request.RequestContextHolder; 18 | import org.springframework.web.context.request.ServletRequestAttributes; 19 | 20 | import javax.servlet.http.HttpServletRequest; 21 | import java.lang.reflect.Method; 22 | import java.util.concurrent.TimeUnit; 23 | 24 | /** 25 | * 重复提交aop 26 | * @author xwolf 27 | * @version 1.0 28 | * @since 1.8 29 | */ 30 | @Order 31 | @Aspect 32 | @Component 33 | @Slf4j 34 | public class AvoidRepeatableCommitAspect { 35 | 36 | @Autowired 37 | private RedisTemplate redisTemplate; 38 | 39 | /** 40 | * @param point 41 | */ 42 | @Around("@annotation(com.xwolf.boot.annotation.AvoidRepeatableCommit)") 43 | public Object around(ProceedingJoinPoint point) throws Throwable { 44 | 45 | HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); 46 | String ip = IPUtil.getIP(request); 47 | //获取注解 48 | MethodSignature signature = (MethodSignature) point.getSignature(); 49 | Method method = signature.getMethod(); 50 | //目标类、方法 51 | String className = method.getDeclaringClass().getName(); 52 | String name = method.getName(); 53 | String ipKey = String.format("%s#%s",className,name); 54 | int hashCode = Math.abs(ipKey.hashCode()); 55 | String key = String.format("%s_%d",ip,hashCode); 56 | log.info("ipKey={},hashCode={},key={}",ipKey,hashCode,key); 57 | AvoidRepeatableCommit avoidRepeatableCommit = method.getAnnotation(AvoidRepeatableCommit.class); 58 | long timeout = avoidRepeatableCommit.timeout(); 59 | if (timeout < 0){ 60 | timeout = Constants.AVOID_REPEATABLE_TIMEOUT; 61 | } 62 | String value = (String) redisTemplate.opsForValue().get(key); 63 | if (StringUtils.isNotBlank(value)){ 64 | return "请勿重复提交"; 65 | } 66 | redisTemplate.opsForValue().set(key, UUIDUtil.uuid(),timeout,TimeUnit.MILLISECONDS); 67 | //执行方法 68 | Object object = point.proceed(); 69 | return object; 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/config/Constants.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.config; 2 | 3 | /** 4 | * 常量 5 | * @author xwolf 6 | * @since 1.8 7 | * @version 1.0.0 8 | **/ 9 | public class Constants { 10 | 11 | /** 12 | * 默认年月日格式化 13 | */ 14 | public static final String DATE_DEFAULT_FORMAT = "YYYY-MM-DD"; 15 | 16 | /** 17 | * 默认日期时间格式化 18 | */ 19 | public static final String DATETIME_DEFAULT_FORMAT = "YYYY-MM-DD HH:mm:ss"; 20 | 21 | /** 22 | * 默认时间格式化 23 | */ 24 | public static final String TIME_DEFAULT_FORMAT = "HH:mm:ss"; 25 | 26 | /** 27 | * 重复提交默认时间30000毫秒 28 | */ 29 | public static final long AVOID_REPEATABLE_TIMEOUT = 30000 ; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/config/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.alibaba.druid.support.http.StatViewServlet; 5 | import com.alibaba.druid.support.http.WebStatFilter; 6 | import com.google.common.collect.Lists; 7 | import com.google.common.collect.Maps; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.boot.bind.RelaxedPropertyResolver; 11 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 12 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 13 | import org.springframework.context.ApplicationContextException; 14 | import org.springframework.context.EnvironmentAware; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Configuration; 17 | import org.springframework.core.env.Environment; 18 | import org.springframework.util.StringUtils; 19 | 20 | import javax.sql.DataSource; 21 | import java.sql.SQLException; 22 | import java.util.Map; 23 | 24 | /** 25 | * 数据源 26 | * @author xwolf 27 | * @date 2017-02-25 08:14 28 | * @since 1.8 29 | * @version 1.0.0 30 | */ 31 | @Configuration 32 | public class DataSourceConfig implements EnvironmentAware{ 33 | 34 | private static final Logger log = LoggerFactory.getLogger(DataSourceConfig.class); 35 | 36 | private RelaxedPropertyResolver prop; 37 | 38 | private Environment environment; 39 | 40 | @Override 41 | public void setEnvironment(Environment environment) { 42 | this.environment = environment; 43 | this.prop = new RelaxedPropertyResolver(environment,"spring.datasource."); 44 | } 45 | 46 | /** 47 | * 数据库连接池配置 48 | * @return 49 | */ 50 | @Bean(initMethod="init",destroyMethod="close",name="dataSource") 51 | public DataSource dataSource(){ 52 | log.info("数据库连接池配置中......"); 53 | if (StringUtils.isEmpty(prop.getProperty("url"))) { 54 | throw new ApplicationContextException("数据库连接池url配置错误."); 55 | }else{ 56 | DruidDataSource druid=new DruidDataSource(); 57 | druid.setUrl(prop.getProperty("url")); 58 | druid.setUsername(prop.getProperty("username")); 59 | druid.setPassword(prop.getProperty("password")); 60 | druid.setDriverClassName(prop.getProperty("driverClassName")); 61 | druid.setInitialSize(Integer.valueOf(prop.getProperty("druid.initialSize"))); 62 | druid.setMinIdle(Integer.valueOf(prop.getProperty("druid.minIdle"))); 63 | druid.setMaxActive(Integer.valueOf(prop.getProperty("druid.maxActive"))); 64 | druid.setMaxWait(Integer.valueOf(prop.getProperty("druid.maxWait"))); 65 | druid.setTimeBetweenConnectErrorMillis(Long.valueOf(prop.getProperty("druid.timeBetweenEvictionRunsMillis"))); 66 | druid.setMinEvictableIdleTimeMillis(Long.valueOf(prop.getProperty("druid.minEvictableIdleTimeMillis"))); 67 | druid.setValidationQuery(prop.getProperty("druid.validationQuery")); 68 | druid.setTestWhileIdle(Boolean.parseBoolean(prop.getProperty("druid.testWhileIdle"))); 69 | druid.setTestOnBorrow(Boolean.parseBoolean(prop.getProperty("druid.testOnBorrow"))); 70 | druid.setTestOnReturn(Boolean.parseBoolean(prop.getProperty("druid.testOnReturn"))); 71 | druid.setConnectionProperties(prop.getProperty("druid.connectionProperties")); 72 | try { 73 | druid.setFilters(prop.getProperty("druid.filter")); 74 | } catch (SQLException e) { 75 | log.error("druid数据库连接池初始化异常"); 76 | } 77 | return druid; 78 | } 79 | } 80 | 81 | /** 82 | * 静态资源过滤 83 | * @return 84 | */ 85 | @Bean 86 | public FilterRegistrationBean filterRegistrationBean() { 87 | FilterRegistrationBean fr = new FilterRegistrationBean(); 88 | fr.setFilter(new WebStatFilter()); 89 | fr.addUrlPatterns("/*"); 90 | fr.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); 91 | return fr; 92 | } 93 | 94 | /** 95 | * 数据源监控 96 | */ 97 | @Bean 98 | public ServletRegistrationBean servletRegistrationBean() { 99 | ServletRegistrationBean registration = new ServletRegistrationBean(); 100 | registration.setServlet(new StatViewServlet()); 101 | registration.setName("druidMonitor"); 102 | registration.setUrlMappings(Lists.newArrayList("/druid/*")); 103 | //自定义添加初始化参数 104 | Map intParams = Maps.newHashMap(); 105 | intParams.put("loginUsername","druid"); 106 | intParams.put("loginPassword","druid"); 107 | registration.setName("DruidWebStatFilter"); 108 | registration.setInitParameters(intParams); 109 | return registration; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/config/FilterConfig.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.config; 2 | 3 | import com.xwolf.boot.interceptor.XSSFilter; 4 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * Filter注册 10 | * @author xwolf 11 | * @version 1.0 12 | * @since 1.8 13 | */ 14 | @Configuration 15 | public class FilterConfig { 16 | 17 | private static final String[] URLS = {"/user/*"}; 18 | 19 | @Bean 20 | public FilterRegistrationBean filterRegistrationBean(){ 21 | 22 | FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); 23 | filterRegistrationBean.setFilter(new XSSFilter()); 24 | filterRegistrationBean.addUrlPatterns(URLS); 25 | filterRegistrationBean.setName("XSSFilter"); 26 | filterRegistrationBean.setOrder(1); 27 | return filterRegistrationBean; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/config/InterceptorConfig.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.config; 2 | 3 | import com.xwolf.boot.interceptor.CsrfInterceptor; 4 | import com.xwolf.boot.interceptor.ErrorInterceptor; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 9 | 10 | /** 11 | * 拦截器配置 12 | * @author xwolf 13 | * @version 1.0 14 | * @since 1.8 15 | */ 16 | @Configuration 17 | public class InterceptorConfig extends WebMvcConfigurerAdapter { 18 | 19 | /** 20 | * 拦截白名单 21 | */ 22 | private static final String[] EXCLUDE_PATH={"/swagger-ui.html","/swagger-resources/**","/v2/api-docs"}; 23 | 24 | /** 25 | * CSRF拦截 26 | * @return 27 | */ 28 | @Bean 29 | CsrfInterceptor csrfInterceptor(){ 30 | return new CsrfInterceptor(); 31 | } 32 | /** 33 | * 错误拦截 34 | * @return 35 | */ 36 | @Bean 37 | ErrorInterceptor errorInterceptor(){ 38 | return new ErrorInterceptor(); 39 | } 40 | 41 | @Override 42 | public void addInterceptors(InterceptorRegistry registry) { 43 | 44 | registry.addInterceptor(csrfInterceptor()).addPathPatterns("/**").excludePathPatterns(EXCLUDE_PATH); 45 | 46 | registry.addInterceptor(errorInterceptor()).addPathPatterns("/**").excludePathPatterns(EXCLUDE_PATH); 47 | super.addInterceptors(registry); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.builders.PathSelectors; 7 | import springfox.documentation.builders.RequestHandlerSelectors; 8 | import springfox.documentation.service.ApiInfo; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 12 | 13 | /** 14 | *

15 | * swagger 整合管理API接口 16 | * 参考http://www.jianshu.com/p/8033ef83a8ed 17 | *

18 | * @author xwolf 19 | * @since 1.8 20 | * @version 1.0.0 21 | */ 22 | @Configuration 23 | @EnableSwagger2 24 | public class SwaggerConfig { 25 | 26 | @Bean 27 | public Docket createRestApi() { 28 | return new Docket(DocumentationType.SWAGGER_2) 29 | .apiInfo(apiInfo()) 30 | .select() 31 | .apis(RequestHandlerSelectors.basePackage("com.xwolf.boot.controller")) 32 | .paths(PathSelectors.any()) 33 | .build(); 34 | } 35 | 36 | private ApiInfo apiInfo() { 37 | return new ApiInfoBuilder() 38 | .title("Spring Boot中使用Swagger2构建RESTful APIs") 39 | .description("Swagger API 接口文档") 40 | .contact("程序猿") 41 | .version("1.0") 42 | .build(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/controller/ApiController.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.controller; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.xwolf.boot.api.ApiBaseController; 5 | import com.xwolf.boot.entity.User; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * Swagger API测试Controller,以Map代替CRUD 14 | * @author xwolf 15 | * @since 1.8 16 | * @version 1.0.0 17 | */ 18 | @RestController 19 | @RequestMapping(value="/api") 20 | public class ApiController implements ApiBaseController { 21 | 22 | private static Map users = Maps.newConcurrentMap(); 23 | 24 | @GetMapping(value={"/list"}) 25 | @Override 26 | public List getUserList() { 27 | List r = new ArrayList(users.values()); 28 | return r; 29 | } 30 | 31 | @PostMapping(value="/add") 32 | @Override 33 | public String postUser(@RequestBody User user) { 34 | users.put(user.getUid(), user); 35 | return "success"; 36 | } 37 | 38 | @Override 39 | @GetMapping(value="/{id:\\d+}") 40 | public User getUser(@PathVariable Integer id) { 41 | return users.get(id); 42 | } 43 | 44 | @Override 45 | @PutMapping(value="/{id:\\d+}") 46 | public String putUser(@PathVariable Integer id, @RequestBody User user) { 47 | User u = users.get(id); 48 | u.setUname(user.getUname()); 49 | users.put(id, u); 50 | return "success"; 51 | } 52 | 53 | @Override 54 | @DeleteMapping(value="/{id:\\d+}") 55 | public String deleteUser(@PathVariable Integer id) { 56 | users.remove(id); 57 | return "success"; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/controller/ErrorController.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | /** 7 | * 对应响应码跳转 8 | * @author xwolf 9 | * @version 1.0 10 | * @since 1.8 11 | */ 12 | @Controller 13 | public class ErrorController { 14 | 15 | @GetMapping("500") 16 | public String error500(){ 17 | return "500"; 18 | } 19 | 20 | @GetMapping("404") 21 | public String error404(){ 22 | return "404"; 23 | } 24 | 25 | @GetMapping("400") 26 | public String error400(){ 27 | return "400"; 28 | } 29 | 30 | @GetMapping("302") 31 | public String error302(){ 32 | return "302"; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.controller; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.xwolf.boot.annotation.AvoidRepeatableCommit; 5 | import com.xwolf.boot.api.UserBaseController; 6 | import com.xwolf.boot.entity.User; 7 | import com.xwolf.boot.service.IUserService; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.validation.Valid; 13 | import java.util.List; 14 | 15 | /** 16 | * 17 | * @author xwolf 18 | * @since 1.8 19 | * @version 1.0.0 20 | */ 21 | @RestController 22 | @RequestMapping("user") 23 | @Slf4j 24 | public class UserController implements UserBaseController { 25 | 26 | @Autowired 27 | private IUserService userService; 28 | 29 | /** 30 | * 添加用户 31 | * @param user 32 | * @return 33 | */ 34 | @PostMapping(value = "add") 35 | @AvoidRepeatableCommit(timeout = 50000) 36 | @Override 37 | public String insert(@Valid User user){ 38 | // user.setBirth(new Date()); 39 | log.info("请求参数:{}",user); 40 | return userService.insert(user); 41 | } 42 | 43 | /** 44 | * 获取用户列表 45 | * @param start 46 | * @param size 47 | * @return 48 | */ 49 | @GetMapping(value = "list/{start}/{size}") 50 | @Override 51 | public List getUserList(@PathVariable("start")int start,@PathVariable("size")int size){ 52 | PageHelper.startPage(start,size); 53 | List list= userService.getList(); 54 | return list; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/dao/IUserDao.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.dao; 2 | 3 | import com.xwolf.boot.entity.User; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author xwolf 9 | * @date 2017-02-25 09:07 10 | * @since 1.8 11 | * @version 1.0.0 12 | */ 13 | public interface IUserDao { 14 | 15 | int insert(User user); 16 | 17 | List queryList(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.entity; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import com.xwolf.boot.config.Constants; 5 | import lombok.Data; 6 | import lombok.ToString; 7 | import org.hibernate.validator.constraints.Length; 8 | import org.hibernate.validator.constraints.NotBlank; 9 | 10 | import java.util.Date; 11 | 12 | /** 13 | * 用户 14 | * @author xwolf 15 | * @since 1.8 16 | * @version 1.0.0 17 | */ 18 | @Data 19 | @ToString 20 | public class User { 21 | 22 | /** 23 | * 用户ID 24 | */ 25 | private int uid; 26 | 27 | /** 28 | * 用户名 29 | */ 30 | @NotBlank(message ="用户名不能为空") 31 | @Length(min = 5,max =32,message = "用户名长度在5-32") 32 | private String uname; 33 | 34 | /** 35 | * 生日 36 | */ 37 | @JsonFormat(pattern = Constants.DATE_DEFAULT_FORMAT) 38 | private Date birth; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/interceptor/CsrfInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.interceptor; 2 | 3 | import com.xwolf.boot.utils.StringUtils; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.web.servlet.HandlerInterceptor; 6 | import org.springframework.web.servlet.ModelAndView; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.util.Arrays; 11 | 12 | /** 13 | * csrf拦截referer 14 | * @author xwolf 15 | * @version 1.0 16 | * @since 1.8 17 | */ 18 | 19 | @Slf4j 20 | public class CsrfInterceptor implements HandlerInterceptor { 21 | 22 | /** 23 | * 默认白名单 24 | */ 25 | private static final String[] WHITE_URLS ={"baidu.com","localhost.com"}; 26 | 27 | @Override 28 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { 29 | String userAgent = request.getHeader("User-Agent"); 30 | //此处仅处理referer 31 | String referer = request.getHeader("Referer"); 32 | String url = request.getRequestURI(); 33 | log.info("preHandle request agent={}, referer={},URI={}",userAgent,referer,url); 34 | boolean contains = true ; 35 | if ( StringUtils.isNotBlank(referer) ){ 36 | 37 | final String host = referer.split("://")[1].split("/")[0]; 38 | 39 | contains = Arrays.stream(WHITE_URLS).anyMatch( u -> u.contains(host)); 40 | } 41 | 42 | return contains; 43 | } 44 | 45 | @Override 46 | public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { 47 | 48 | } 49 | 50 | @Override 51 | public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/interceptor/ErrorInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.interceptor; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.servlet.HandlerInterceptor; 5 | import org.springframework.web.servlet.ModelAndView; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | /** 11 | * 不同的状态码跳转不同的页面 12 | * @author xwolf 13 | * @version 1.0 14 | * @since 1.8 15 | */ 16 | @Slf4j 17 | public class ErrorInterceptor implements HandlerInterceptor { 18 | 19 | 20 | @Override 21 | public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { 22 | return true; 23 | } 24 | 25 | @Override 26 | public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { 27 | String uri = httpServletRequest.getRequestURI(); 28 | int status = httpServletResponse.getStatus(); 29 | log.info("uri={},status={}",uri,status); 30 | 31 | switch (status){ 32 | case 500: 33 | modelAndView.setViewName("500"); 34 | break; 35 | case 400: 36 | modelAndView.setViewName("400"); 37 | break; 38 | case 404: 39 | modelAndView.setViewName("404"); 40 | break; 41 | case 302: 42 | modelAndView.setViewName("302"); 43 | break; 44 | } 45 | } 46 | 47 | @Override 48 | public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/interceptor/XSSFilter.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.interceptor; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.http.HttpServletRequest; 5 | import java.io.IOException; 6 | 7 | /** 8 | * XSS过滤器 9 | * @author xwolf 10 | * @since 1.8 11 | */ 12 | public class XSSFilter implements Filter { 13 | 14 | private FilterConfig filterConfig = null; 15 | 16 | @Override 17 | public void init(FilterConfig filterConfig) throws ServletException { 18 | this.filterConfig = filterConfig; 19 | } 20 | 21 | @Override 22 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 23 | chain.doFilter(new XSSHttpServletRequestWrapper((HttpServletRequest) request), response); 24 | } 25 | 26 | @Override 27 | public void destroy() { 28 | this.filterConfig = null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/interceptor/XSSHttpServletRequestWrapper.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.interceptor; 2 | 3 | 4 | import org.apache.commons.lang3.StringEscapeUtils; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletRequestWrapper; 8 | 9 | /** 10 | * XSS 过滤 11 | * @author xwolf 12 | * @since 1.8 13 | */ 14 | public class XSSHttpServletRequestWrapper extends HttpServletRequestWrapper { 15 | /** 16 | * Constructs a request object wrapping the given request. 17 | * 18 | * @param request 19 | * @throws IllegalArgumentException if the request is null 20 | */ 21 | public XSSHttpServletRequestWrapper(HttpServletRequest request) { 22 | super(request); 23 | } 24 | 25 | @Override 26 | public String[] getParameterValues(String parameter) { 27 | String[] values = super.getParameterValues(parameter); 28 | if (values==null) { 29 | return null; 30 | } 31 | int count = values.length; 32 | String[] encodedValues = new String[count]; 33 | for (int i = 0; i < count; i++) { 34 | encodedValues[i] = StringEscapeUtils.escapeHtml4(values[i]).replace("'","''"); 35 | } 36 | return encodedValues; 37 | } 38 | @Override 39 | public String getParameter(String parameter) { 40 | String value = super.getParameter(parameter); 41 | if (value == null) { 42 | return null; 43 | } 44 | return StringEscapeUtils.escapeHtml4(value).replace("'","''"); 45 | } 46 | @Override 47 | public String getHeader(String name) { 48 | String value = super.getHeader(name); 49 | if (value == null) { 50 | return null; 51 | } 52 | 53 | return StringEscapeUtils.escapeHtml4(value).replace("'","''"); 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/service/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.service; 2 | 3 | import com.xwolf.boot.entity.User; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author xwolf 9 | * @date 2017-02-25 09:16 10 | * @since 1.8 11 | * @version 1.0.0 12 | */ 13 | public interface IUserService { 14 | 15 | String insert(User user); 16 | 17 | List getList(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.service.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.xwolf.boot.dao.IUserDao; 5 | import com.xwolf.boot.entity.User; 6 | import com.xwolf.boot.service.IUserService; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * 用户Service 15 | * @author xwolf 16 | * @date 2017-02-25 09:17 17 | * @since V1.0.0 18 | */ 19 | @Slf4j 20 | @Service 21 | public class UserServiceImpl implements IUserService { 22 | 23 | @Autowired 24 | private IUserDao userDao; 25 | 26 | /** 27 | * 新增用户 28 | * @param user 用户信息 29 | * @return 30 | */ 31 | @Override 32 | public String insert(User user) { 33 | int resultInt=userDao.insert(user); 34 | JSONObject result = new JSONObject(); 35 | if(resultInt>0){ 36 | result.put("success",true); 37 | result.put("msg","成功"); 38 | }else{ 39 | result.put("success",false); 40 | result.put("msg","失败"); 41 | } 42 | return result.toJSONString(); 43 | } 44 | 45 | /** 46 | * 获取用户列表 47 | * @return 48 | */ 49 | @Override 50 | public List getList() { 51 | return userDao.queryList(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/utils/IPUtil.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.utils; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | /** 6 | * IP工具 7 | * @author xwolf 8 | * @since 1.8 9 | */ 10 | public class IPUtil { 11 | 12 | /** 13 | * 获取IP地址 14 | * @param request 15 | * @return 16 | */ 17 | public static String getIP(HttpServletRequest request) { 18 | if (request == null) { 19 | return "unknown"; 20 | } 21 | String ip = request.getHeader("x-forwarded-for"); 22 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 23 | ip = request.getHeader("Proxy-Client-IP"); 24 | } 25 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 26 | ip = request.getHeader("X-Forwarded-For"); 27 | } 28 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 29 | ip = request.getHeader("WL-Proxy-Client-IP"); 30 | } 31 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 32 | ip = request.getHeader("X-Real-IP"); 33 | } 34 | 35 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 36 | ip = request.getRemoteAddr(); 37 | } 38 | return ip; 39 | } 40 | 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.utils; 2 | 3 | /** 4 | * 字符串工具 5 | * @author xwolf 6 | * @version 1.0 7 | * @since 1.8 8 | */ 9 | public class StringUtils { 10 | 11 | /** 12 | * 是否为空字符串 13 | * @param str 14 | * @return 15 | */ 16 | public static boolean isBlank(String str){ 17 | int strLen; 18 | if (str == null || (strLen = str.length()) == 0) { 19 | return true; 20 | } 21 | for (int i = 0; i < strLen; i++) { 22 | if (Character.isWhitespace(str.charAt(i)) == false) { 23 | return false; 24 | } 25 | } 26 | return true; 27 | } 28 | 29 | public static boolean isNotBlank(String str){ 30 | return !isBlank(str); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/xwolf/boot/utils/UUIDUtil.java: -------------------------------------------------------------------------------- 1 | package com.xwolf.boot.utils; 2 | 3 | import java.util.UUID; 4 | 5 | /** 6 | * @author xwolf 7 | * @version 1.0 8 | * @since 1.8 9 | */ 10 | public class UUIDUtil { 11 | 12 | public static String uuid(){ 13 | return UUID.randomUUID().toString().replace("-","").toLowerCase(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: boot 4 | http: 5 | encoding: 6 | force: true 7 | charset: UTF-8 8 | enabled: true 9 | 10 | profiles: 11 | active: dev 12 | 13 | jackson: 14 | date-format: YYYY-MM-DD 15 | joda-date-time-format: YYYY-MM-DD HH:mm:ss 16 | 17 | redis: 18 | database: 0 19 | host: localhost 20 | password: 21 | port: 6379 22 | 23 | thymeleaf: 24 | mode: HTML5 25 | encoding: UTF-8 26 | prefix: classpath:/templates/ 27 | suffix: .html 28 | cache: false 29 | content-type: text/html 30 | mybatis: 31 | mapper-locations: classpath:mapper/*.xml 32 | type-aliases-package: com.xwolf.boot.entity 33 | check-config-location: true 34 | config-location: classpath:mybatis.xml 35 | 36 | logging: 37 | level: info 38 | config: classpath:logback.xml 39 | 40 | server: 41 | port: 8082 42 | session: 43 | timeout: 1800 44 | connection-timeout: 60000 45 | display-name: Boot Application 46 | 47 | --- 48 | spring: 49 | profiles: dev 50 | datasource: 51 | driver-class-name: com.mysql.jdbc.Driver 52 | username: eop 53 | url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&createDatabaseIfNotExist=true 54 | password: 123456 55 | type: com.alibaba.druid.pool.DruidDataSource 56 | druid: 57 | filters: config 58 | maxActive: 50 59 | initialSize: 10 60 | maxWait: 60000 61 | minIdle: 1 62 | timeBetweenEvictionRunsMillis: 60000 63 | minEvictableIdleTimeMillis: 300000 64 | validationQuery: select 'x' 65 | testWhileIdle: true 66 | testOnBorrow: false 67 | testOnReturn: false 68 | connectionProperties: config.decrypt=false;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMBqy+oGF0DhV2jiHyilb4mowR4mgQL4FSE0+GvlstTqYanSnJXYHmAffYVNO7lsAq4KU0K3Xh9e6qtGdAevFq0CAwEAAQ== 69 | 70 | --- 71 | spring: 72 | profiles: test 73 | datasource: 74 | driver-class-name: com.mysql.jdbc.Driver 75 | username: eop 76 | url: jdbc:mysql://127.0.0.1:3306/wifi2?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&createDatabaseIfNotExist=true 77 | password: eop@eop 78 | type: com.alibaba.druid.pool.DruidDataSource 79 | druid: 80 | filters: config 81 | maxActive: 50 82 | initialSize: 10 83 | maxWait: 60000 84 | minIdle: 1 85 | timeBetweenEvictionRunsMillis: 60000 86 | minEvictableIdleTimeMillis: 300000 87 | validationQuery: select 'x' 88 | testWhileIdle: true 89 | testOnBorrow: false 90 | testOnReturn: false 91 | connectionProperties: config.decrypt=false;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMBqy+oGF0DhV2jiHyilb4mowR4mgQL4FSE0+GvlstTqYanSnJXYHmAffYVNO7lsAq4KU0K3Xh9e6qtGdAevFq0CAwEAAQ== -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - 9 | %msg%n 10 | 11 | 12 | 13 | 15 | /var/log/boot/boot.log 16 | 17 | boot.log.%i.bak 18 | 1 19 | 12 20 | 21 | 23 | 1000MB 24 | 25 | 26 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - 27 | %msg%n 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | uid,uname,birth 14 | 15 | 16 | INSERT INTO user (uid, uname,birth) 17 | VALUES (#{uid,jdbcType=INTEGER}, #{uname,jdbcType=VARCHAR},#{birth,jdbcType=TIMESTAMP}) 18 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /src/main/resources/mybatis.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/resources/templates/302.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 302 6 | 7 | 8 | 9 |

10 | 无权限访问. 11 |

12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/400.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 400 6 | 7 | 8 | 9 |

10 | 请求参数错误. 11 |

12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 404 6 | 7 | 8 | 9 |

10 | 访问的资源不存在 11 |

12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 500 6 | 7 | 8 | 9 |

10 | 服务器内部错误. 11 |

12 | 13 | -------------------------------------------------------------------------------- /src/test/java/com/xwolf/BootApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.xwolf; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class BootApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------