├── .travis.yml ├── spring-boot-archetype-web ├── src │ └── main │ │ ├── resources │ │ ├── application-test.properties │ │ ├── application-dev.properties │ │ ├── application-prod.properties │ │ ├── application.properties │ │ └── config │ │ │ └── logging-config.xml │ │ └── java │ │ └── com │ │ └── github │ │ └── netyjq │ │ └── archetype │ │ ├── ApplicationBootstrap.java │ │ └── web │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ ├── FastJsonConverter.java │ │ └── BeanConfig.java │ │ ├── aspect │ │ ├── RequestParamAspect.java │ │ └── GlobalExceptionAspect.java │ │ └── controller │ │ └── AppInfoController.java └── pom.xml ├── spring-boot-archetype-model ├── src │ └── main │ │ └── java │ │ └── com │ │ └── github │ │ └── netyjq │ │ └── archetype │ │ └── model │ │ ├── AbstractModel.java │ │ ├── dto │ │ ├── AbstractDTO.java │ │ ├── request │ │ │ ├── AppInfoRequestDTO.java │ │ │ └── PageRequestDTO.java │ │ └── response │ │ │ ├── ResponseDTO.java │ │ │ └── PageResponseDTO.java │ │ └── domain │ │ └── AppInfo.java └── pom.xml ├── spring-boot-archetype-common ├── src │ └── main │ │ └── java │ │ └── com │ │ └── github │ │ └── netyjq │ │ └── archetype │ │ └── common │ │ ├── validation │ │ ├── ValidationMarker.java │ │ └── MyValidator.java │ │ ├── exception │ │ ├── SessionInvalidException.java │ │ ├── ServiceException.java │ │ ├── AbstractException.java │ │ └── ParamInvalidException.java │ │ ├── enums │ │ └── ErrorEnum.java │ │ └── util │ │ └── BeanUtil.java └── pom.xml ├── spring-boot-archetype-mapper ├── src │ └── main │ │ └── java │ │ └── com │ │ └── github │ │ └── netyjq │ │ └── archetype │ │ └── mapper │ │ └── AppInfoMapper.java └── pom.xml ├── spring-boot-archetype-service ├── src │ └── main │ │ └── java │ │ └── com │ │ └── github │ │ └── netyjq │ │ └── archetype │ │ └── service │ │ └── AppInfoService.java └── pom.xml ├── LICENSE ├── README-CN.md ├── README.md ├── .gitignore └── pom.xml /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - openjdk8 5 | 6 | install: 7 | mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V 8 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | # data source config 2 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true 3 | spring.datasource.username=root 4 | spring.datasource.password=123456 5 | 6 | logging.path=/opt/{spring.application.name}/ -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | # data source config 2 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false 3 | spring.datasource.username=root 4 | spring.datasource.password=123456 5 | 6 | # set log path 7 | logging.path=logs -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/resources/application-prod.properties: -------------------------------------------------------------------------------- 1 | # data source config 2 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true 3 | spring.datasource.username=root 4 | spring.datasource.password=123456 5 | 6 | 7 | logging.path=/opt/{spring.application.name}/ -------------------------------------------------------------------------------- /spring-boot-archetype-model/src/main/java/com/github/netyjq/archetype/model/AbstractModel.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * abstract database model,used to marked as a database pojo class. 7 | * @date 2017/6/6. 8 | * @author netyjq@gmail.com 9 | */ 10 | public abstract class AbstractModel implements Serializable { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /spring-boot-archetype-model/src/main/java/com/github/netyjq/archetype/model/dto/AbstractDTO.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.model.dto; 2 | 3 | /** 4 | * abstract DTO class, only with a method validate() used to validate parameters. 5 | * @author netyjq@gmail.com 6 | * @date 2019-04-29 7 | */ 8 | public abstract class AbstractDTO { 9 | 10 | /** 11 | * 参数验证 12 | * @return boolean 13 | */ 14 | public abstract boolean validate(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/validation/ValidationMarker.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.validation; 2 | 3 | /** 4 | * this used with @Validate 5 | * 6 | * @author netyjq@gmail.com 7 | * @date 2019-04-28 8 | */ 9 | public class ValidationMarker { 10 | 11 | public interface InsertGroup{} 12 | 13 | public interface UpdateGroup{} 14 | 15 | public interface SelectGroup{} 16 | 17 | public interface DeleteGroup{} 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /spring-boot-archetype-model/src/main/java/com/github/netyjq/archetype/model/domain/AppInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.model.domain; 2 | 3 | import com.github.netyjq.archetype.model.AbstractModel; 4 | import lombok.Data; 5 | 6 | /** 7 | * entity 示例 8 | * @author yejq@gmail.com 9 | * @date 2019-06-05 10 | */ 11 | @Data 12 | public class AppInfo extends AbstractModel { 13 | 14 | private Integer id; 15 | 16 | /** 17 | * 应用名称 18 | */ 19 | private String name; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/exception/SessionInvalidException.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.exception; 2 | 3 | /** 4 | * @author netyjq@gmail.com 5 | * @date 2019-05-05 6 | */ 7 | public class SessionInvalidException extends AbstractException { 8 | 9 | public SessionInvalidException(String message) { 10 | super(message); 11 | } 12 | 13 | @Override 14 | String buildErrorMessage() { 15 | return null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spring-boot-archetype-mapper/src/main/java/com/github/netyjq/archetype/mapper/AppInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.github.netyjq.archetype.model.domain.AppInfo; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | * 9 | * a mapper class example, others mapper should extends BaseMapper like this 10 | * 11 | * @date 2019/9/25 16:16 12 | * @author netyjq@gmail.com 13 | **/ 14 | @Mapper 15 | public interface AppInfoMapper extends BaseMapper { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/exception/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.exception; 2 | 3 | 4 | import com.github.netyjq.archetype.common.enums.ErrorEnum; 5 | 6 | /** 7 | * @author netyjq@gmail.com 8 | * @date 2019-04-28 9 | */ 10 | public class ServiceException extends AbstractException { 11 | 12 | @Override 13 | String buildErrorMessage() { 14 | return ErrorEnum.BIZ_ERROR.buildMessage(this.getMessage()).toString(); 15 | } 16 | 17 | public ServiceException(String message) { 18 | super(message); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/exception/AbstractException.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.exception; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author netyjq@gmail.com 7 | * @date 2019-04-28 8 | */ 9 | @Data 10 | public abstract class AbstractException extends RuntimeException { 11 | 12 | private String message; 13 | 14 | /** 15 | * build error message 16 | * @return String 17 | */ 18 | abstract String buildErrorMessage(); 19 | 20 | public AbstractException(String message) { 21 | this.message = message; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /spring-boot-archetype-service/src/main/java/com/github/netyjq/archetype/service/AppInfoService.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.github.netyjq.archetype.mapper.AppInfoMapper; 5 | import com.github.netyjq.archetype.model.domain.AppInfo; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * a service class example, other services class should extends ServiceImpl like this 10 | * 11 | * @date 2019/12/13 12 | * @author netyjq@gmail.com 13 | */ 14 | @Service 15 | public class AppInfoService extends ServiceImpl { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/java/com/github/netyjq/archetype/ApplicationBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype; 2 | 3 | 4 | import org.mybatis.spring.annotation.MapperScan; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | 8 | /** 9 | * SpringBoot bootstrap 10 | * @date 2017/6/7 11 | * @author netyjq@gmail.com 12 | */ 13 | @SpringBootApplication 14 | @MapperScan("com.github.netyjq.archetype.mapper") 15 | public class ApplicationBootstrap { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(ApplicationBootstrap.class, args); 19 | } 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/exception/ParamInvalidException.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.exception; 2 | 3 | import com.github.netyjq.archetype.common.enums.ErrorEnum; 4 | import lombok.Data; 5 | 6 | /** 7 | * parameter invalid error 8 | * 9 | * @author netyjq@gmail.com 10 | * @date 2019-04-28 11 | */ 12 | @Data 13 | public class ParamInvalidException extends AbstractException { 14 | 15 | private String field; 16 | 17 | @Override 18 | String buildErrorMessage() { 19 | return ErrorEnum.WEB_PARAM_ERROR.buildMessage(this.getMessage()).toString(); 20 | } 21 | 22 | public ParamInvalidException(String field, String message) { 23 | super("parameter: " + field + message); 24 | this.field = field; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /spring-boot-archetype-model/src/main/java/com/github/netyjq/archetype/model/dto/request/AppInfoRequestDTO.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.model.dto.request; 2 | 3 | import com.github.netyjq.archetype.common.validation.ValidationMarker; 4 | import lombok.Data; 5 | 6 | import javax.validation.constraints.NotNull; 7 | 8 | /** 9 | * AppInfo RequestDTO Example 10 | * @date 2017/7/30 11 | * @author netyjq@gamil.com 12 | */ 13 | @Data 14 | public class AppInfoRequestDTO extends PageRequestDTO { 15 | 16 | @NotNull(groups = {ValidationMarker.UpdateGroup.class}) 17 | private Integer id; 18 | 19 | @NotNull(groups = {ValidationMarker.InsertGroup.class, ValidationMarker.UpdateGroup.class}) 20 | private String name; 21 | 22 | @Override 23 | public boolean validate() { 24 | return true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ## active profile 2 | spring.profiles.active=@activatedProperties@ 3 | 4 | ## application name 5 | spring.application.name=spring-boot-archetype 6 | 7 | # data source config 8 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 9 | spring.datasource.sql-script-encoding=utf-8 10 | 11 | ## mybatis config 12 | mybatis.typeAliasesPackage=com.github.netyjq.archetype.model.domain 13 | mybatis.mapperLocations=classpath:mapper/*.xml 14 | 15 | #pagehelper 16 | pagehelper.helperDialect=mysql 17 | pagehelper.reasonable=true 18 | pagehelper.supportMethodsArguments=true 19 | pagehelper.params=count=countSql 20 | 21 | server.port=8080 22 | 23 | ## encoding 24 | spring.http.encoding.charset=UTF-8 25 | spring.http.encoding.force=true 26 | spring.http.encoding.enabled=true 27 | server.tomcat.uri-encoding=UTF-8 28 | 29 | ## log config 30 | logging.config=classpath:config/logging-config.xml 31 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 YJQ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/java/com/github/netyjq/archetype/web/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.web.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import org.mybatis.spring.annotation.MapperScan; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.transaction.annotation.EnableTransactionManagement; 8 | 9 | /** 10 | * mybatis plus config 11 | * more detail see https://github.com/baomidou/mybatis-plus 12 | * @date 2019/12/13 13 | * @author netyjq@gmail.com 14 | */ 15 | @EnableTransactionManagement 16 | @Configuration 17 | public class MybatisPlusConfig { 18 | 19 | @Bean 20 | public PaginationInterceptor paginationInterceptor() { 21 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 22 | // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false 23 | // paginationInterceptor.setOverflow(false); 24 | // 设置最大单页限制数量,默认 500 条,-1 不受限制 25 | // paginationInterceptor.setLimit(500); 26 | return paginationInterceptor; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-boot-archetype-model/src/main/java/com/github/netyjq/archetype/model/dto/request/PageRequestDTO.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.model.dto.request; 2 | 3 | import com.github.netyjq.archetype.model.dto.AbstractDTO; 4 | import lombok.Data; 5 | import org.hibernate.validator.constraints.Range; 6 | 7 | /** 8 | * 分页请求dto 9 | * @date 2017/2/20 10 | * @author netyjq@gmail.com 11 | */ 12 | @Data 13 | public class PageRequestDTO extends AbstractDTO { 14 | 15 | private long pageNum = 1; 16 | 17 | @Range(min = 0, max = 100) 18 | private long pageSize = 5; 19 | 20 | public PageRequestDTO() { 21 | } 22 | 23 | public PageRequestDTO setPageSize(Integer pageSize) { 24 | if (pageSize < 1) { 25 | pageSize = 1; 26 | } 27 | this.pageSize = pageSize; 28 | return this; 29 | } 30 | 31 | public PageRequestDTO setPageNum(Integer pageNum) { 32 | if (pageNum < 0) { 33 | pageNum = 1; 34 | } 35 | this.pageNum = pageNum; 36 | return this; 37 | } 38 | 39 | public PageRequestDTO(Integer pageNum, Integer pageSize) { 40 | setPageNum(pageNum); 41 | setPageSize(pageSize); 42 | } 43 | 44 | @Override 45 | public boolean validate() { 46 | return false; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /spring-boot-archetype-model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | spring-boot-archetype 7 | com.github.netyjq 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | spring-boot-archetype-model 13 | 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 3.2 20 | 21 | 1.8 22 | 1.8 23 | UTF-8 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | com.github.netyjq 32 | spring-boot-archetype-common 33 | 1.0-SNAPSHOT 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /spring-boot-archetype-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | spring-boot-archetype 7 | com.github.netyjq 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | spring-boot-archetype-service 13 | 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 3.2 20 | 21 | 1.8 22 | 1.8 23 | UTF-8 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | com.github.netyjq 32 | spring-boot-archetype-mapper 33 | 1.0-SNAPSHOT 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /spring-boot-archetype-mapper/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | spring-boot-archetype 7 | com.github.netyjq 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | spring-boot-archetype-mapper 13 | 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 3.2 20 | 21 | 1.8 22 | 1.8 23 | UTF-8 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | com.github.netyjq 33 | spring-boot-archetype-model 34 | 1.0-SNAPSHOT 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/java/com/github/netyjq/archetype/web/aspect/RequestParamAspect.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.web.aspect; 2 | 3 | import com.github.netyjq.archetype.common.validation.MyValidator; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.aspectj.lang.annotation.Before; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.validation.BindingResult; 9 | 10 | /** 11 | * this class used to validate parameters in spring controllers. 12 | * 13 | * to make sure it works, you must use @Validated annotations and declare a BindingResult Object. 14 | * for example : 15 | * public ResponseDTO query(@Validated({ValidationMarker.SelectGroup.class}) AppInfoRequestDTO requestDTO, BindingResult result) { 16 | * 17 | * } 18 | * 19 | * @date 2017/7/24 20 | * @author netyjq@gmail.com 21 | */ 22 | @Aspect 23 | @Component 24 | public class RequestParamAspect { 25 | 26 | /** 27 | * Verify the section BindingResult type parameter based on Hibernate MyValidator 28 | */ 29 | @Before("execution(* com.github.netyjq.archetype.web.controller.*.*(..))") 30 | public void doBefore(JoinPoint joinPoint) { 31 | Object [] args = joinPoint.getArgs(); 32 | for (Object object : args) { 33 | if (object instanceof BindingResult) { 34 | BindingResult result = (BindingResult) object; 35 | MyValidator.validateBindResult(result); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spring-boot-archetype-model/src/main/java/com/github/netyjq/archetype/model/dto/response/ResponseDTO.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.model.dto.response; 2 | 3 | import com.github.netyjq.archetype.common.enums.ErrorEnum; 4 | import lombok.Data; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * common-used response class used to return data to browser by spring controllers. 11 | * @date 2017/2/20. 12 | * @author netyjq@gmail.com 13 | */ 14 | @Data 15 | public class ResponseDTO { 16 | 17 | /** 18 | * 响应code 19 | */ 20 | private Integer result; 21 | 22 | /** 23 | * 响应的message 24 | */ 25 | private Object message; 26 | 27 | /** 28 | * 响应的数据 29 | */ 30 | private Object data; 31 | 32 | public ResponseDTO() { 33 | this.result = ErrorEnum.SUCCESS.getCode(); 34 | this.message = ErrorEnum.SUCCESS.getMsg(); 35 | } 36 | 37 | public ResponseDTO(ErrorEnum errorEnum) { 38 | this.result = errorEnum.getCode(); 39 | this.message = errorEnum.getMsg(); 40 | } 41 | 42 | public ResponseDTO(Object object) { 43 | this.data = object; 44 | this.result = ErrorEnum.SUCCESS.getCode(); 45 | this.message = ErrorEnum.SUCCESS.getMsg(); 46 | } 47 | 48 | public ResponseDTO(Object object, String key) { 49 | Map map = new HashMap(); 50 | map.put(key, object); 51 | this.data = map; 52 | this.result = ErrorEnum.SUCCESS.getCode(); 53 | this.message = ErrorEnum.SUCCESS.getMsg(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/enums/ErrorEnum.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.enums; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | 6 | /** 7 | * Back and forth interactive status code 8 | * 9 | * @date 2016/12/8. 10 | * @author netyjq@gmail.com 11 | */ 12 | @NoArgsConstructor 13 | @Getter 14 | public enum ErrorEnum { 15 | 16 | /** 17 | * request successful 18 | */ 19 | SUCCESS(200, "success"), 20 | 21 | /** 22 | * business error 23 | */ 24 | BIZ_ERROR(1000, "business error"), 25 | 26 | /** 27 | * session expired 28 | */ 29 | SESSION_EXPIRED_ERROR(1001, "your session was expired"), 30 | 31 | /** 32 | * runtime error 33 | */ 34 | RUNTIME_ERROR(3000, "system error, please try again later"), 35 | 36 | /** 37 | * parameters error 38 | */ 39 | WEB_PARAM_ERROR(3001, "parameter error"), 40 | 41 | /** 42 | * db error 43 | */ 44 | DB_EXECUTE_ERROR(3002, "db error"), 45 | 46 | /** 47 | * rpc error 48 | */ 49 | RPC_ERROR(4000, "remote service error"), 50 | 51 | /** 52 | * unknown error 53 | */ 54 | UNKNOWN_ERROR(6000, "unknown error"); 55 | 56 | private int code; 57 | 58 | private String msg; 59 | 60 | ErrorEnum(int code, String msg) { 61 | this.code = code; 62 | this.msg = msg; 63 | } 64 | 65 | public ErrorEnum buildMessage(String msg) { 66 | this.msg = msg; 67 | return this; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return msg + "." + this.name() + ", code:" + code; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/java/com/github/netyjq/archetype/web/config/FastJsonConverter.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.web.config; 2 | 3 | import com.alibaba.fastjson.serializer.SerializerFeature; 4 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; 5 | import com.google.common.collect.Lists; 6 | import org.springframework.http.MediaType; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * fast-json config, you can replace any other http json converter by yourself. 12 | * 13 | * @date 2017/6/19 14 | * @author netyjq@gmail.com.com 15 | */ 16 | public class FastJsonConverter extends FastJsonHttpMessageConverter { 17 | 18 | public FastJsonConverter() { 19 | com.alibaba.fastjson.support.config.FastJsonConfig fastJsonConfig = new com.alibaba.fastjson.support.config.FastJsonConfig(); 20 | fastJsonConfig.setSerializerFeatures( 21 | SerializerFeature.PrettyFormat 22 | ); 23 | 24 | // 解决乱码 25 | FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); 26 | List supportedMediaTypes = Lists.newArrayList(); 27 | supportedMediaTypes.add(MediaType.parseMediaType("text/html;charset=UTF-8")); 28 | supportedMediaTypes.add(MediaType.parseMediaType("application/json")); 29 | fastConverter.setSupportedMediaTypes(supportedMediaTypes); 30 | 31 | // 定义时间和null输出处理 32 | fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); 33 | fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue); 34 | this.setFastJsonConfig(fastJsonConfig); 35 | } 36 | 37 | @Override 38 | protected boolean supports(Class clazz) { 39 | return super.supports(clazz); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /README-CN.md: -------------------------------------------------------------------------------- 1 | ## SpringBoot Maven Archetype 脚手架 2 | [![Build Status](https://travis-ci.org/netyjq/spring-boot-archetype.svg?branch=master)](https://travis-ci.org/netyjq/spring-boot-archetype) 3 | 4 | ### 简介 5 | 6 | **`spring-boot-archetype`** 是一个maven脚手架,用于快速构建高效、稳定且代码干净的`spring-boot`项目。只要您安装了`Maven`, 7 | 或者您使用`Intellij IDEA`进行编码,只需简单的几个步骤,就能基于 **`spring-boot-archetype`** 构建一个新的`spring-boot`项目。 8 | 9 | ### 特性 10 | - 支持`maven profile`动态打包`war`或者`jar`运行 11 | - 控制层统一入参验证 12 | - 通用`Model`,`Mapper`,`Service` 让你立马开始写业务代码 13 | - 整合`mybatis-plus3` 14 | - 整合`swagger-ui` 15 | - 整合`lombok` 16 | - 全局异常封装处理 17 | - `logger`支持`profile` 18 | - 遵循阿里巴巴Java开发规范 19 | - 各类实用工具封装 20 | - ... 21 | 22 | ### Maven依赖坐标信息 23 | 24 | ```xml 25 | 26 | com.github.netyjq 27 | spring-boot-archetype 28 | 0.0.2.release 29 | 30 | ``` 31 | 32 | ### 使用 33 | 34 | #### 通过`Maven`命令行创建新项目 35 | 36 | 确保你已经安装了`Maven`,然后在你的终端上输入下面的命令,一段时间后,maven会提示你输入你的项目的`groupId`、`artifactId`、`version`、 37 | `package`,之后你的项目就会自动构建成功。 38 | 39 | ``` 40 | mvn archetype:generate -DarchetypeGroupId=com.github.netyjq -DarchetypeArtifactId=spring-boot-archetype -DarchetypeVersion=0.0.2.release 41 | ``` 42 | 43 | #### 通过 `Intellij IDEA` 创建新项目 44 | 45 | 1. 打开 `Intellij IDEA`,点击导航按钮:文件>新建>项目> 46 | 2. 选择Maven,选中复选框 "Create from Archetype",然后点击按钮 "Add Archetype" 47 | 3. 然后您将看到一个表单,依次填写`groupId`、`artifactId`、`version`,Maven坐标信息上面有 。 48 | 4. 在列表中选择你刚刚添加 "Archetype",逐步创建项目,新项目将自动完成构建。 49 | 50 | **注意:Add Archetype 步骤只需执行一次,以后可直接选择 `spring-boot-archetype:0.0.2.release`** 51 | 52 | ### Contact 53 | - Gmail: netyjq@gmail.com 54 | - Wechat: eWVrYXlqcQ== 55 | 56 | ### End 57 | 欢迎fork, star。有任何问题请提[issue](https://github.com/netyjq/spring-boot-archetype/issues)。 58 | 59 | 60 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/validation/MyValidator.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.validation; 2 | 3 | import com.github.netyjq.archetype.common.exception.ParamInvalidException; 4 | import org.springframework.validation.BindingResult; 5 | import org.springframework.validation.FieldError; 6 | 7 | import javax.validation.ConstraintViolation; 8 | import javax.validation.Validation; 9 | import javax.validation.Validator; 10 | import javax.validation.ValidatorFactory; 11 | import java.util.List; 12 | import java.util.Set; 13 | 14 | /** 15 | * Hibernate validator 16 | * 17 | * @date 2017/6/5 18 | * @author netyjq@gmail.com 19 | */ 20 | public class MyValidator { 21 | 22 | /** 23 | * 验证前端参数,有错误直接抛出异常 24 | * @param result BindResult 25 | * @throws ParamInvalidException 参数异常 26 | * @return 27 | */ 28 | public static void validateBindResult(BindingResult result) throws ParamInvalidException { 29 | if (result !=null && result.hasErrors()) { 30 | List errors = result.getFieldErrors(); 31 | for (FieldError error : errors) { 32 | throw new ParamInvalidException(error.getField(), error.getDefaultMessage()); 33 | } 34 | } 35 | } 36 | 37 | /** 38 | * Hibernate MyValidator 验证器 39 | * @param object 需要校验的对象 40 | * @throws ParamInvalidException 参数异常 41 | */ 42 | public static void validate(Object object) throws ParamInvalidException { 43 | ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 44 | Validator validator = factory.getValidator(); 45 | Set> constraintViolations = validator.validate(object); 46 | for (ConstraintViolation constraintViolation : constraintViolations) { 47 | throw new ParamInvalidException(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage()); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/java/com/github/netyjq/archetype/web/config/BeanConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.web.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.http.converter.HttpMessageConverter; 6 | import org.springframework.transaction.annotation.EnableTransactionManagement; 7 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | import springfox.documentation.builders.PathSelectors; 10 | import springfox.documentation.builders.RequestHandlerSelectors; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * Beans configurations 19 | * @date 2017/6/7. 20 | * @author netyjq@gmail.com 21 | */ 22 | @Configuration 23 | @EnableTransactionManagement 24 | @EnableSwagger2 25 | public class BeanConfig implements WebMvcConfigurer { 26 | 27 | @Override 28 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 29 | registry.addResourceHandler("swagger-ui.html") 30 | .addResourceLocations("classpath:/META-INF/resources/"); 31 | 32 | registry.addResourceHandler("/webjars/**") 33 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 34 | registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); 35 | } 36 | 37 | 38 | @Override 39 | public void configureMessageConverters(List> converters) { 40 | converters.add(fastJsonConverter()); 41 | } 42 | 43 | @Bean 44 | public FastJsonConverter fastJsonConverter() { 45 | return new FastJsonConverter(); 46 | } 47 | 48 | 49 | @Bean 50 | public Docket api() { 51 | return new Docket(DocumentationType.SWAGGER_2) 52 | .select() 53 | .apis(RequestHandlerSelectors.any()) 54 | .paths(PathSelectors.any()) 55 | .build(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## SpringBoot Maven Archetype 2 | [![Build Status](https://travis-ci.org/netyjq/spring-boot-archetype.svg?branch=master)](https://travis-ci.org/netyjq/spring-boot-archetype) 3 | 4 | [中文文档](https://github.com/netyjq/spring-boot-archetype/blob/master/README-CN.md) 5 | 6 | ### Introduction 7 | 8 | **`spring-boot-archetype`** is a maven scaffold for quickly building efficient, clean, and stable `spring-boot` projects. 9 | As long as you have `Maven` installed, or you encode using `Intellij IDEA`, you can build a new `spring-boot` project 10 | based on **`spring-boot-archetype`** in a few simple steps. 11 | 12 | ### Properties 13 | - packaged to jar or war according to active profile 14 | - Unified `@RequestMapping` input verification 15 | - `BaseModel`,`BaseMapper`,`BaseService` supported, write code at once 16 | - `mybatis-plus3` supported 17 | - `swagger-ui` supported 18 | - `lombok` supported 19 | - Global exception encapsulation handling 20 | - `logger` with `profile` supported 21 | - Follow the alibaba p3c specification 22 | - Various utility packages 23 | - ... 24 | 25 | ### Maven Dependency 26 | 27 | ```xml 28 | 29 | com.github.netyjq 30 | spring-boot-archetype 31 | 0.0.2.release 32 | 33 | ``` 34 | 35 | ### Usage 36 | 37 | #### Use with maven command-line 38 | 39 | Make sure you have already installed maven, and then type the command below to your terminal, 40 | 41 | after a while, maven will tips you input your project's `groupId`, `artifactId`, `version`, `package`, then your project will be automatically built successfully. 42 | 43 | ``` 44 | mvn archetype:generate -DarchetypeGroupId=com.github.netyjq -DarchetypeArtifactId=spring-boot-archetype -DarchetypeVersion=0.0.2.release 45 | ``` 46 | 47 | #### Use with Intellij IDEA 48 | 49 | 1. Open the Intellij IDEA, click the navigation button: File > new > Project > 50 | 2. Choose Maven, Check the checkbox "Create from Archetype", then click button "Add Archetype" 51 | 3. Then you will see a form, just enter the 'pom' information. 52 | 4. Select the "Archetype" you just added in the list, step by step, and the new project will automatically complete the build. 53 | 54 | ### Contact 55 | - Gmail: netyjq@gmail.com 56 | - Wechat: eWVrYXlqcQ== 57 | 58 | ### End 59 | I am glad with your fork or star, any question please submit a [issue](https://github.com/netyjq/spring-boot-archetype/issues). 60 | 61 | 62 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/resources/config/logging-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logback 5 | 6 | 7 | 8 | 9 | 10 | ${LOG_PATH}/logs/error/error.log 11 | 12 | ${LOG_PATH}/logs/error/error.log.%d{yyyy-MM-dd-HH} 13 | 30 14 | 15 | 16 | ERROR 17 | ACCEPT 18 | DENY 19 | 20 | 21 | %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n 22 | 23 | 24 | 25 | 26 | 27 | ${LOG_PATH}/logs/info/info.log 28 | 29 | ${LOG_PATH}/logs/info/info.log.%d{yyyy-MM-dd-HH} 30 | 30 31 | 32 | 33 | INFO 34 | ACCEPT 35 | DENY 36 | 37 | 38 | %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n 39 | 40 | 41 | 42 | 43 | 44 | 45 | %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/java/com/github/netyjq/archetype/web/controller/AppInfoController.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.web.controller; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 7 | import com.github.netyjq.archetype.common.exception.ServiceException; 8 | import com.github.netyjq.archetype.common.validation.ValidationMarker; 9 | import com.github.netyjq.archetype.model.domain.AppInfo; 10 | import com.github.netyjq.archetype.model.dto.request.AppInfoRequestDTO; 11 | import com.github.netyjq.archetype.model.dto.response.ResponseDTO; 12 | import com.github.netyjq.archetype.service.AppInfoService; 13 | import com.google.common.base.Strings; 14 | import io.swagger.annotations.Api; 15 | import io.swagger.annotations.ApiOperation; 16 | import org.springframework.validation.BindingResult; 17 | import org.springframework.validation.annotation.Validated; 18 | import org.springframework.web.bind.annotation.RequestMapping; 19 | import org.springframework.web.bind.annotation.RequestMethod; 20 | import org.springframework.web.bind.annotation.RestController; 21 | 22 | import javax.annotation.Resource; 23 | 24 | /** 25 | * rest example controller 26 | * @author netyjq@@gmail.com 27 | * @date 2017/7/5 28 | */ 29 | @RestController 30 | @Api(tags = "AppInfo") 31 | public class AppInfoController { 32 | 33 | @Resource 34 | private AppInfoService appInfoService; 35 | 36 | @ApiOperation(value = "query", notes = "query example") 37 | @RequestMapping(value = "/query", method = RequestMethod.POST) 38 | public ResponseDTO query(@Validated({ValidationMarker.SelectGroup.class}) AppInfoRequestDTO requestDTO, BindingResult result) { 39 | IPage page = appInfoService.page(new Page<>(requestDTO.getPageNum(), requestDTO.getPageSize()), 40 | new QueryWrapper() 41 | .lambda() 42 | .eq(!Strings.isNullOrEmpty(requestDTO.getName()), AppInfo::getName, requestDTO.getName()) 43 | ); 44 | return new ResponseDTO(page); 45 | } 46 | 47 | @ApiOperation(value = "update", notes = "update example") 48 | @RequestMapping(value = "/update", method = RequestMethod.POST) 49 | public ResponseDTO update(@Validated({ValidationMarker.UpdateGroup.class}) AppInfoRequestDTO appInfoRequestDTO, BindingResult result) { 50 | AppInfo appInfo = appInfoService.getById(appInfoRequestDTO.getId()); 51 | if (null == appInfo) { 52 | throw new ServiceException("no AppInfo was found."); 53 | } 54 | boolean isSuccess = appInfoService.update(appInfo, new UpdateWrapper() 55 | .lambda() 56 | .set(AppInfo::getName, appInfoRequestDTO.getName()) 57 | .eq(AppInfo::getId, appInfoRequestDTO.getId()) 58 | ); 59 | if (!isSuccess) { 60 | throw new ServiceException("update failed, please try again later."); 61 | } 62 | return new ResponseDTO(appInfoService.list(new QueryWrapper<>())); 63 | } 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /spring-boot-archetype-model/src/main/java/com/github/netyjq/archetype/model/dto/response/PageResponseDTO.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.model.dto.response; 2 | 3 | import com.github.netyjq.archetype.model.dto.request.PageRequestDTO; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * common-used response class used to return List data to browser by spring controllers. 12 | * @date 2017/6/6. 13 | * @author netyjq@gmail.com 14 | */ 15 | @Data 16 | public class PageResponseDTO implements Serializable { 17 | 18 | /** 19 | * 数据集合 20 | */ 21 | private List content; 22 | 23 | /** 24 | * 数据库几记录总数 25 | */ 26 | private long total = 0; 27 | 28 | /** 29 | * 页码 30 | */ 31 | private long pageNo = 1; 32 | 33 | /** 34 | * 每页数据大小 35 | */ 36 | private long pageSize = 1; 37 | 38 | /** 39 | * 总页数 40 | */ 41 | private long totalPage = 1; 42 | 43 | public PageResponseDTO empty(PageRequestDTO baseDTO) { 44 | this.setPageSize(baseDTO.getPageSize()); 45 | this.setPageNo(baseDTO.getPageNum()); 46 | this.setTotal(0); 47 | this.setTotalPage(0); 48 | this.setContent(new ArrayList()); 49 | return this; 50 | } 51 | 52 | public PageResponseDTO(List content, long total, long pageNo, long pageSize) { 53 | this.content = content; 54 | this.total = total; 55 | this.pageNo = pageNo; 56 | this.pageSize = pageSize; 57 | this.totalPage = getTotalPage(); 58 | } 59 | 60 | public PageResponseDTO(List content, long total, PageRequestDTO baseDTO) { 61 | this.content = content; 62 | this.total = total; 63 | this.pageNo = baseDTO.getPageNum(); 64 | this.pageSize = baseDTO.getPageSize(); 65 | } 66 | 67 | public List getContent() { 68 | if(this.content == null){ 69 | this.content = new ArrayList(); 70 | } 71 | return content; 72 | } 73 | 74 | public PageResponseDTO setContent(List content) { 75 | this.content = content; 76 | return this; 77 | } 78 | 79 | 80 | public PageResponseDTO setTotal(long total) { 81 | this.total = total; 82 | return this; 83 | } 84 | 85 | 86 | public PageResponseDTO setPageNo(long pageNo) { 87 | this.pageNo = pageNo; 88 | return this; 89 | } 90 | 91 | 92 | public PageResponseDTO setPageSize(long pageSize) { 93 | this.pageSize = pageSize; 94 | return this; 95 | } 96 | 97 | public long getTotalPage() { 98 | if (this.total == 0 || this.total < pageSize) { 99 | this.totalPage = 1; 100 | } else { 101 | this.totalPage = this.total % pageSize == 0 ? this.total / this.pageSize : (this.total / this.pageSize) + 1; 102 | } 103 | return totalPage; 104 | } 105 | 106 | public void setTotalPage(Integer totalPage) { 107 | this.totalPage = totalPage; 108 | } 109 | 110 | @Override 111 | public String toString() { 112 | return "PageResponseDTO{" + 113 | "content=" + content + 114 | ", total=" + total + 115 | ", pageNo=" + pageNo + 116 | ", pageSize=" + pageSize + 117 | ", totalPage=" + totalPage + 118 | '}'; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | spring-boot-archetype 7 | com.github.netyjq 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | spring-boot-archetype-common 13 | 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-compiler-plugin 19 | 3.2 20 | 21 | 1.8 22 | 1.8 23 | UTF-8 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-logging 40 | 41 | 42 | 43 | org.springframework 44 | spring-test 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-test 49 | 50 | 51 | 52 | org.springframework 53 | spring-context-support 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-aop 59 | 60 | 61 | 62 | 63 | com.alibaba 64 | fastjson 65 | 1.2.58 66 | 67 | 68 | 69 | 70 | com.google.guava 71 | guava 72 | 73 | 74 | 75 | 76 | org.hibernate 77 | hibernate-validator 78 | 79 | 80 | 81 | mysql 82 | mysql-connector-java 83 | 8.0.28 84 | 85 | 86 | 87 | com.baomidou 88 | mybatis-plus-boot-starter 89 | 90 | 91 | 92 | io.springfox 93 | springfox-swagger2 94 | 95 | 96 | 97 | io.springfox 98 | springfox-swagger-ui 99 | 100 | 101 | 102 | org.projectlombok 103 | lombok 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | spring-boot-archetype 7 | com.github.netyjq 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | spring-boot-archetype-web 13 | 14 | 15 | spring-boot-archetype 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 3.2 21 | 22 | 1.8 23 | 1.8 24 | UTF-8 25 | 26 | 27 | 28 | 29 | 30 | src/main/resources 31 | true 32 | 33 | 34 | 35 | 36 | 37 | 38 | dev 39 | 40 | dev 41 | jar 42 | 43 | 44 | true 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 1.5.3.RELEASE 52 | 53 | 54 | 55 | repackage 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | test 66 | 67 | test 68 | war 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-starter-tomcat 74 | provided 75 | 76 | 77 | 78 | 79 | 80 | prod 81 | 82 | prod 83 | war 84 | 85 | 86 | 87 | org.springframework.boot 88 | spring-boot-starter-tomcat 89 | provided 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | com.github.netyjq 99 | spring-boot-archetype-service 100 | 1.0-SNAPSHOT 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,java,maven,windows,intellij+all 3 | # Edit at https://www.gitignore.io/?templates=osx,java,maven,windows,intellij+all 4 | 5 | ### Intellij+all ### 6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 8 | 9 | # User-specific stuff 10 | .idea/**/workspace.xml 11 | .idea/**/tasks.xml 12 | .idea/**/usage.statistics.xml 13 | .idea/**/dictionaries 14 | .idea/**/shelf 15 | 16 | # Generated files 17 | .idea/**/contentModel.xml 18 | 19 | # Sensitive or high-churn files 20 | .idea/**/dataSources/ 21 | .idea/**/dataSources.ids 22 | .idea/**/dataSources.local.xml 23 | .idea/**/sqlDataSources.xml 24 | .idea/**/dynamic.xml 25 | .idea/**/uiDesigner.xml 26 | .idea/**/dbnavigator.xml 27 | 28 | # Gradle 29 | .idea/**/gradle.xml 30 | .idea/**/libraries 31 | 32 | # Gradle and Maven with auto-import 33 | # When using Gradle or Maven with auto-import, you should exclude module files, 34 | # since they will be recreated, and may cause churn. Uncomment if using 35 | # auto-import. 36 | # .idea/modules.xml 37 | # .idea/*.iml 38 | # .idea/modules 39 | # *.iml 40 | # *.ipr 41 | 42 | # CMake 43 | cmake-build-*/ 44 | 45 | # Mongo Explorer plugin 46 | .idea/**/mongoSettings.xml 47 | 48 | # File-based project format 49 | *.iws 50 | 51 | # IntelliJ 52 | out/ 53 | 54 | # mpeltonen/sbt-idea plugin 55 | .idea_modules/ 56 | 57 | # JIRA plugin 58 | atlassian-ide-plugin.xml 59 | 60 | # Cursive Clojure plugin 61 | .idea/replstate.xml 62 | 63 | # Crashlytics plugin (for Android Studio and IntelliJ) 64 | com_crashlytics_export_strings.xml 65 | crashlytics.properties 66 | crashlytics-build.properties 67 | fabric.properties 68 | 69 | # Editor-based Rest Client 70 | .idea/httpRequests 71 | 72 | # Android studio 3.1+ serialized cache file 73 | .idea/caches/build_file_checksums.ser 74 | 75 | ### Intellij+all Patch ### 76 | # Ignores the whole .idea folder and all .iml files 77 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 78 | 79 | .idea/ 80 | 81 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 82 | 83 | *.iml 84 | modules.xml 85 | .idea/misc.xml 86 | *.ipr 87 | 88 | # Sonarlint plugin 89 | .idea/sonarlint 90 | 91 | ### Java ### 92 | # Compiled class file 93 | *.class 94 | 95 | # Log file 96 | *.log 97 | 98 | # BlueJ files 99 | *.ctxt 100 | 101 | # Mobile Tools for Java (J2ME) 102 | .mtj.tmp/ 103 | 104 | # Package Files # 105 | *.jar 106 | *.war 107 | *.nar 108 | *.ear 109 | *.zip 110 | *.tar.gz 111 | *.rar 112 | 113 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 114 | hs_err_pid* 115 | 116 | ### Maven ### 117 | target/ 118 | pom.xml.tag 119 | pom.xml.releaseBackup 120 | pom.xml.versionsBackup 121 | pom.xml.next 122 | release.properties 123 | dependency-reduced-pom.xml 124 | buildNumber.properties 125 | .mvn/timing.properties 126 | .mvn/wrapper/maven-wrapper.jar 127 | .flattened-pom.xml 128 | 129 | ### OSX ### 130 | # General 131 | .DS_Store 132 | .AppleDouble 133 | .LSOverride 134 | 135 | # Icon must end with two \r 136 | Icon 137 | 138 | # Thumbnails 139 | ._* 140 | 141 | # Files that might appear in the root of a volume 142 | .DocumentRevisions-V100 143 | .fseventsd 144 | .Spotlight-V100 145 | .TemporaryItems 146 | .Trashes 147 | .VolumeIcon.icns 148 | .com.apple.timemachine.donotpresent 149 | 150 | # Directories potentially created on remote AFP share 151 | .AppleDB 152 | .AppleDesktop 153 | Network Trash Folder 154 | Temporary Items 155 | .apdisk 156 | 157 | ### Windows ### 158 | # Windows thumbnail cache files 159 | Thumbs.db 160 | Thumbs.db:encryptable 161 | ehthumbs.db 162 | ehthumbs_vista.db 163 | 164 | # Dump file 165 | *.stackdump 166 | 167 | # Folder config file 168 | [Dd]esktop.ini 169 | 170 | # Recycle Bin used on file shares 171 | $RECYCLE.BIN/ 172 | 173 | # Windows Installer files 174 | *.cab 175 | *.msi 176 | *.msix 177 | *.msm 178 | *.msp 179 | 180 | # Windows shortcuts 181 | *.lnk 182 | 183 | # End of https://www.gitignore.io/api/osx,java,maven,windows,intellij+all 184 | 185 | -------------------------------------------------------------------------------- /spring-boot-archetype-web/src/main/java/com/github/netyjq/archetype/web/aspect/GlobalExceptionAspect.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.web.aspect; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.github.netyjq.archetype.common.enums.ErrorEnum; 6 | import com.github.netyjq.archetype.common.exception.ParamInvalidException; 7 | import com.github.netyjq.archetype.common.exception.ServiceException; 8 | import com.github.netyjq.archetype.common.exception.SessionInvalidException; 9 | import com.github.netyjq.archetype.common.validation.MyValidator; 10 | import com.github.netyjq.archetype.model.dto.response.ResponseDTO; 11 | import org.apache.ibatis.exceptions.PersistenceException; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.validation.BindException; 15 | import org.springframework.validation.BindingResult; 16 | import org.springframework.web.bind.annotation.ControllerAdvice; 17 | import org.springframework.web.bind.annotation.ExceptionHandler; 18 | 19 | import javax.annotation.Resource; 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | import java.io.PrintWriter; 23 | import java.sql.SQLException; 24 | 25 | /** 26 | * global exception handler 27 | * 28 | * @date 2017/8/16 29 | * @author netyjq@gmail.com 30 | */ 31 | @ControllerAdvice 32 | public class GlobalExceptionAspect { 33 | 34 | private static Logger logger = LoggerFactory.getLogger(GlobalExceptionAspect.class); 35 | 36 | @Resource 37 | private HttpServletRequest request; 38 | 39 | @Resource 40 | HttpServletResponse response; 41 | 42 | /** 43 | * 业务异常 44 | * @param e ServiceException 45 | */ 46 | @ExceptionHandler(ServiceException.class) 47 | public void serviceException(ServiceException e) { 48 | writeToClient(ErrorEnum.BIZ_ERROR.buildMessage(e.getMessage()), e); 49 | } 50 | 51 | /** 52 | * SQL异常 53 | * @param e SQLException 54 | */ 55 | @ExceptionHandler(SQLException.class) 56 | public void sqlException(SQLException e) { 57 | writeToClient(ErrorEnum.DB_EXECUTE_ERROR, e); 58 | } 59 | 60 | /** 61 | * mybatis异常拦截 62 | * @param e 63 | */ 64 | @ExceptionHandler(PersistenceException.class) 65 | public void persistenceException(PersistenceException e) { 66 | writeToClient(ErrorEnum.DB_EXECUTE_ERROR, e); 67 | } 68 | 69 | /** 70 | * 参数业务 71 | * @param e ParamValidException 72 | */ 73 | @ExceptionHandler(ParamInvalidException.class) 74 | public void paramInvalidException(ParamInvalidException e) { 75 | writeToClient(ErrorEnum.WEB_PARAM_ERROR.buildMessage(e.getMessage()), e); 76 | } 77 | 78 | @ExceptionHandler(SessionInvalidException.class) 79 | public void sessionInvalidException(SessionInvalidException e) { 80 | writeToClient(ErrorEnum.SESSION_EXPIRED_ERROR.buildMessage(e.getMessage()), e); 81 | } 82 | 83 | 84 | /** 85 | * 绑定异常 86 | * @param e 87 | */ 88 | @ExceptionHandler(BindException.class) 89 | public void bindException(BindException e) { 90 | BindingResult result = e.getBindingResult(); 91 | if (result.hasErrors()) { 92 | MyValidator.validateBindResult(result); 93 | } 94 | } 95 | 96 | @ExceptionHandler(NullPointerException.class) 97 | public void nullPointerException(NullPointerException e) { 98 | writeToClient(ErrorEnum.UNKNOWN_ERROR, e); 99 | } 100 | 101 | private void writeToClient(ErrorEnum errorEnum, Exception e) { 102 | ResponseDTO responseDTO = new ResponseDTO(); 103 | responseDTO.setResult(errorEnum.getCode()); 104 | responseDTO.setMessage(errorEnum.getMsg()); 105 | write(JSON.toJSONString(responseDTO), e); 106 | } 107 | 108 | private void write(String message, Exception e) { 109 | PrintWriter pw = null; 110 | try { 111 | response.setContentType("application/json;charset=UTF-8" ); 112 | pw = response.getWriter(); 113 | pw.write(message); 114 | pw.flush(); 115 | } catch (Exception ex) { 116 | } finally { 117 | if (pw != null) { 118 | pw.close(); 119 | } 120 | logger.error("【统一异常】异常详情: {}, 参数: {}", message, getRequestParams(request), e); 121 | } 122 | } 123 | 124 | /** 125 | * 获取请求的基本参数 126 | * @param request 127 | * @return 128 | */ 129 | private String getRequestParams(HttpServletRequest request) { 130 | JSONObject jsonObject = new JSONObject(); 131 | jsonObject.put("requestUrl", request.getRequestURL()); 132 | jsonObject.put("method", request.getMethod()); 133 | jsonObject.put("parameter", request.getParameterMap()); 134 | return jsonObject.toJSONString(); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /spring-boot-archetype-common/src/main/java/com/github/netyjq/archetype/common/util/BeanUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.netyjq.archetype.common.util; 2 | 3 | import com.google.common.base.Splitter; 4 | import com.google.common.base.Strings; 5 | import org.springframework.util.CollectionUtils; 6 | 7 | import java.beans.BeanInfo; 8 | import java.beans.Introspector; 9 | import java.beans.PropertyDescriptor; 10 | import java.io.*; 11 | import java.lang.reflect.Field; 12 | import java.lang.reflect.Method; 13 | import java.util.*; 14 | import java.util.stream.IntStream; 15 | 16 | /** 17 | * Bean util 18 | * 19 | * @date 2017/6/6. 20 | * @author netyjq@gmail.com 21 | */ 22 | public class BeanUtil { 23 | 24 | /** 25 | * convert bean to Map 26 | * @param object bean 27 | * @return Map 28 | */ 29 | public static Map transBeanToMap(Object object) { 30 | if (object == null) { 31 | return null; 32 | } 33 | Map map = new HashMap(16); 34 | try { 35 | BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass()); 36 | PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); 37 | for (PropertyDescriptor property : propertyDescriptors) { 38 | String key = property.getName(); 39 | if (!"class".equals(key)) { 40 | Method getter = property.getReadMethod(); 41 | Object value = getter.invoke(object); 42 | map.put(key, value); 43 | } 44 | } 45 | } catch (Exception e) { 46 | e.printStackTrace(); 47 | } 48 | return map; 49 | } 50 | 51 | /** 52 | * convert bean to Map with specified fields 53 | * @param source bean 54 | * @param properties fields 55 | * @return 56 | */ 57 | public static Map transBeanToMap(Object source, String properties) { 58 | if (source == null) { 59 | return null; 60 | } 61 | Map map = new HashMap(16); 62 | try { 63 | List propsList = Arrays.asList(properties.replace(" ", "").split(",")); 64 | // 如果数据非常敏感的话,可以先把 T 转成 vo,再反射vo 65 | Class c = Class.forName(source.getClass().getName()); 66 | Field[] fields = c.getDeclaredFields(); 67 | for (Field field : fields) { 68 | field.setAccessible(true); 69 | // 取出属性名称 70 | String propName = field.toString().substring(field.toString().lastIndexOf(".")+1); 71 | if (propsList.indexOf(propName) != -1) { 72 | map.put(propName,field.get(source)); 73 | } 74 | if (map.size() == propsList.size()) { 75 | break; 76 | } 77 | } 78 | 79 | } catch (Exception e) { 80 | e.printStackTrace(); 81 | } 82 | return map; 83 | } 84 | 85 | public static Map transBeanToMap(Object source, Class clazz) { 86 | return transBeanToMap(source, getProperty(clazz)); 87 | } 88 | 89 | 90 | /** 91 | * 批量获取对象中指定属性的值 92 | * @param sourceList Bean集合 93 | * @param properties Bean属性 94 | * @return List> 95 | * @throws ClassNotFoundException 96 | */ 97 | public static List> transBeansToListMap(List sourceList, String properties) throws ClassNotFoundException { 98 | if (CollectionUtils.isEmpty(sourceList) || Strings.isNullOrEmpty(properties)) { 99 | return null; 100 | } 101 | List> objectList = new ArrayList<>(); 102 | sourceList.forEach(source -> { 103 | objectList.add(transBeanToMap(source, properties)); 104 | }); 105 | return objectList; 106 | } 107 | 108 | public static List> transBeansToListMap(List sourceList, Class clazz) throws ClassNotFoundException { 109 | return transBeansToListMap(sourceList, getProperty(clazz)); 110 | } 111 | 112 | /** 113 | * 获取Object属性 举个栗子 对象有a,b,c 3个属性,执行此方法后返回字符串 "a,b,c" 114 | * @param clazz 对象的class 115 | * @return String 116 | */ 117 | public static String getProperty(Class clazz) { 118 | StringBuffer sb = new StringBuffer(); 119 | try { 120 | BeanInfo beanInfo = Introspector.getBeanInfo(clazz); 121 | PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); 122 | for (PropertyDescriptor property : propertyDescriptors) { 123 | String key = property.getName(); 124 | // 过滤class属性 125 | if (!"class".equals(key)) { 126 | sb.append(key); 127 | sb.append(","); 128 | } 129 | } 130 | } catch (Exception e) { 131 | e.printStackTrace(); 132 | } 133 | return sb.toString(); 134 | } 135 | 136 | /** 137 | * 根据key-value构造Map 举个栗子: keys="a,b,c", values:{A, B, C} 138 | * @param keys key值,多个用逗号隔开 139 | * @param values key 对应的value, 必须与 key 保证顺序 140 | * @return Map 141 | */ 142 | public static Map getPropertyMap(String keys, Object... values) { 143 | if (Strings.isNullOrEmpty(keys) || values == null) { 144 | return null; 145 | } 146 | List valueList = new ArrayList<>(); 147 | for (Object o : values) { 148 | valueList.add(o); 149 | } 150 | if (valueList.isEmpty()) { 151 | return null; 152 | } 153 | Map params = new HashMap<>(16); 154 | List keyList = Splitter.on(",").trimResults().splitToList(keys); 155 | IntStream.range(0, keyList.size()).forEach(index -> { 156 | params.put(keyList.get(index), valueList.get(index)); 157 | }); 158 | return params; 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.github.netyjq 8 | spring-boot-archetype 9 | 1.0-SNAPSHOT 10 | 11 | spring-boot-archetype-model 12 | spring-boot-archetype-mapper 13 | spring-boot-archetype-web 14 | spring-boot-archetype-service 15 | spring-boot-archetype-common 16 | 17 | pom 18 | 19 | spring-boot-archetype 20 | help to quickly build efficient, code-clean and stable 'spring-boot' projects. 21 | https://github.com/netyjq/spring-boot-archetype 22 | 23 | 24 | 25 | netyjq 26 | netyjq@gmail.com 27 | netyjq 28 | https://github.com/netyjq/spring-boot-archetype 29 | 30 | 31 | 32 | 33 | 34 | Apache License, Version 2.0 35 | https://www.apache.org/licenses/LICENSE-2.0 36 | 37 | 38 | 39 | 40 | 1.0-SNAPSHOT 41 | https://github.com/netyjq/spring-boot-archetype 42 | 43 | 44 | 45 | UTF-8 46 | UTF-8 47 | true 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-parent 53 | 2.1.7.RELEASE 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | maven-archetype-plugin 62 | 3.1.2 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-source-plugin 67 | 2.2.1 68 | 69 | 70 | package 71 | 72 | jar-no-fork 73 | 74 | 75 | 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-javadoc-plugin 80 | 2.9.1 81 | 82 | 83 | package 84 | 85 | jar 86 | 87 | 88 | 89 | 90 | 91 | org.apache.maven.plugins 92 | maven-gpg-plugin 93 | 1.6 94 | 95 | 96 | verify 97 | 98 | sign 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | ossrh-snapshot 110 | https://oss.sonatype.org/content/repositories/snapshots 111 | 112 | 113 | ossrh-staging 114 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | org.mybatis.spring.boot 125 | mybatis-spring-boot-starter 126 | 1.3.0 127 | 128 | 129 | 130 | com.alibaba 131 | fastjson 132 | 1.2.58 133 | 134 | 135 | 136 | 137 | com.google.guava 138 | guava 139 | 21.0 140 | 141 | 142 | 143 | 144 | org.hibernate 145 | hibernate-validator 146 | 5.3.5.Final 147 | 148 | 149 | 150 | mysql 151 | mysql-connector-java 152 | 5.1.46 153 | runtime 154 | 155 | 156 | 157 | com.baomidou 158 | mybatis-plus-boot-starter 159 | 3.1.2 160 | 161 | 162 | 163 | io.springfox 164 | springfox-swagger2 165 | 2.9.2 166 | 167 | 168 | 169 | io.springfox 170 | springfox-swagger-ui 171 | 2.9.2 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | --------------------------------------------------------------------------------