├── .gitignore ├── README.md ├── command-module ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── rogge │ │ │ └── command │ │ │ ├── CmApplication.java │ │ │ ├── conf │ │ │ ├── MybatisConfigurer.java │ │ │ ├── ProjectConstant.java │ │ │ └── WebMvcConfigurer.java │ │ │ ├── mapper │ │ │ └── CommandContentMapper.java │ │ │ ├── model │ │ │ ├── CommandContent.java │ │ │ ├── User.java │ │ │ └── vo │ │ │ │ └── CommentVO.java │ │ │ ├── service │ │ │ ├── CommandContentService.java │ │ │ └── impl │ │ │ │ └── CommandContentServiceImpl.java │ │ │ └── web │ │ │ └── CommandContentController.java │ └── resources │ │ ├── application.yml │ │ └── mapper │ │ └── CommandContentMapper.xml │ └── test │ └── java │ └── com │ └── rogge │ └── command │ └── CmApplicationTests.java ├── common-module ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── rogge │ │ │ └── common │ │ │ ├── CommonModuleApplication.java │ │ │ ├── Constant.java │ │ │ ├── annotation │ │ │ └── Description.java │ │ │ ├── conf │ │ │ ├── RedisConfig.java │ │ │ ├── SessionConfig.java │ │ │ └── redis │ │ │ │ ├── OnlineUserInfo.java │ │ │ │ ├── RedisDao.java │ │ │ │ ├── RedisSerializer.java │ │ │ │ └── SessionUserInfo.java │ │ │ ├── core │ │ │ ├── AbstractService.java │ │ │ ├── ApiResponse.java │ │ │ ├── ApiResponseVO.java │ │ │ ├── BaseController.java │ │ │ ├── Mapper.java │ │ │ ├── ResponseCode.java │ │ │ ├── Service.java │ │ │ ├── ServiceApiResponse.java │ │ │ └── ServiceException.java │ │ │ ├── intercept │ │ │ └── LoginInterceptor.java │ │ │ ├── model │ │ │ ├── KeyValue.java │ │ │ ├── LanguageEnum.java │ │ │ ├── SessionUser.java │ │ │ ├── User.java │ │ │ └── Visitor.java │ │ │ └── util │ │ │ ├── UUIDGenerator.java │ │ │ └── Util.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── rogge │ └── common │ └── CommonModuleApplicationTests.java ├── config ├── gateway-service-dev.yml └── order-module-dev.yml ├── discovery-module ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── rogge │ │ │ └── discovery │ │ │ └── DiscoveryModuleApplication.java │ └── resources │ │ ├── application.yml │ │ └── properties │ │ ├── gateway-service-dev.yml │ │ └── order-module-dev.yml │ └── test │ └── java │ └── com │ └── rogge │ └── discovery │ └── DiscoveryModuleApplicationTests.java ├── gateway-service ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── rogge │ │ │ └── gateway │ │ │ ├── GatewayServiceApplication.java │ │ │ └── SessionFilter.java │ └── resources │ │ └── bootstrap.yml │ └── test │ └── java │ └── com │ └── rogge │ └── gateway │ └── GatewayServiceApplicationTests.java ├── order-module ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── rogge │ │ │ └── order │ │ │ ├── OrderModuleApplication.java │ │ │ ├── algorithm │ │ │ ├── OrderDatabaseAlgorithm.java │ │ │ └── OrderTableAlgorithm.java │ │ │ ├── conf │ │ │ ├── DataSourceConfig.java │ │ │ ├── FeignConfig.java │ │ │ ├── MybatisConfigurer.java │ │ │ ├── ProjectConstant.java │ │ │ └── WebMvcConfigurer.java │ │ │ ├── feign │ │ │ └── UserFeign.java │ │ │ ├── mapper │ │ │ └── OrderMapper.java │ │ │ ├── model │ │ │ └── Order.java │ │ │ ├── service │ │ │ ├── OrderService.java │ │ │ └── impl │ │ │ │ └── OrderServiceImpl.java │ │ │ └── web │ │ │ └── OrderController.java │ └── resources │ │ ├── bootstrap.yml │ │ ├── mapper │ │ └── OrderMapper.xml │ │ └── order-module-dev.yml │ └── test │ └── java │ └── com │ └── rogge │ └── order │ └── OrderModuleApplicationTests.java ├── pom.xml ├── sql ├── command.sql ├── command_content.sql ├── order_0.sql ├── order_1.sql └── user.sql └── user-module ├── .gitignore ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── rogge │ │ └── user │ │ ├── UmApplication.java │ │ ├── conf │ │ ├── MybatisConfigurer.java │ │ ├── ProjectConstant.java │ │ └── WebMvcConfigurer.java │ │ ├── mapper │ │ └── UserMapper.java │ │ ├── service │ │ ├── UserService.java │ │ └── impl │ │ │ └── UserServiceImpl.java │ │ └── web │ │ └── UserController.java └── resources │ ├── application.yml │ └── mapper │ └── UserMapper.xml └── test └── java └── com └── rogge └── user └── UmApplicationTests.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/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 此工程有6个module 2 | 3 | command-module 为测试动态路由和测试Spring Session Redis 实现的缓存 4 | 5 | common-module 为公库 6 | 7 | discovery-module 为服务注册中心也是服务配置中心 8 | 9 | gateway-service 为网关配置中心 10 | 11 | order-module 为订单模块,订单服务提供者,用户服务消费者 增加Sharding-JDBC分库分表 12 | 13 | user-module 为用户服务提供者 14 | 15 | module启动顺序 先启动discovery-module服务注册中心 16 | 17 | 然后启动redis(必须) 18 | 19 | 再启动getway-service网关配置中心,其他随意 20 | 21 | 需要注意discovery-module 下的application.yml需要配合自己的环境配置,目前有3种配置方式,git(默认) native:file classpath 22 | 23 | 请求顺序 24 | 25 | http://localhost/user/login?id=5   登录(get) 26 | 27 | http://localhost/order/getOrderByUserId?userId=5  获取数据(get) 测试RestTemplate 28 | 29 | http://localhost/order/getOrderByUserIdV2?userId=5  获取数据(get) 测试feign 30 | 31 | http://localhost/order/getOrderByUserIdV3?userId=5 获取数据(get) 测试session粘滞 32 | 33 | http://localhost/order/add 添加订单数据(post) 测试Sharding-JDBC 分库分表 34 | -------------------------------------------------------------------------------- /command-module/.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/ -------------------------------------------------------------------------------- /command-module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.rogge.command 7 | command-module 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | command-module 12 | Demo project for Spring Boot 13 | 14 | 15 | com.rogge 16 | scloud 17 | 0.0.1-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | com.rogge.common 29 | common-module 30 | 0.0.1-SNAPSHOT 31 | jar 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-maven-plugin 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/CmApplication.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.ComponentScan; 8 | import org.springframework.web.client.RestTemplate; 9 | 10 | @SpringBootApplication 11 | @EnableEurekaClient 12 | @ComponentScan(basePackages={"com.rogge.common","com.rogge.command"}) 13 | public class CmApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(CmApplication.class, args); 17 | } 18 | 19 | @Bean 20 | public RestTemplate RestTemplate(){ 21 | return new RestTemplate(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/conf/MybatisConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.conf; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import org.apache.ibatis.plugin.Interceptor; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | import org.mybatis.spring.SqlSessionFactoryBean; 7 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 11 | import org.springframework.core.io.support.ResourcePatternResolver; 12 | import tk.mybatis.spring.mapper.MapperScannerConfigurer; 13 | 14 | import javax.annotation.Resource; 15 | import javax.sql.DataSource; 16 | import java.util.Properties; 17 | 18 | /** 19 | * [Description] 20 | *

21 | * [How to use] 22 | *

23 | * [Tips] 24 | * 25 | * @author Created by Rogge on 2017/10/6 0006. 26 | * @since 1.0.0 27 | */ 28 | @Configuration 29 | public class MybatisConfigurer { 30 | @Resource 31 | private DataSource dataSource; 32 | 33 | @Bean 34 | public SqlSessionFactory sqlSessionFactoryBean() throws Exception { 35 | SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); 36 | bean.setDataSource(dataSource); 37 | bean.setTypeAliasesPackage(ProjectConstant.MODEL_PACKAGE); 38 | 39 | //分页插件 40 | PageHelper pageHelper = new PageHelper(); 41 | Properties properties = new Properties(); 42 | properties.setProperty("reasonable", "true"); 43 | properties.setProperty("supportMethodsArguments", "true"); 44 | properties.setProperty("returnPageInfo", "check"); 45 | properties.setProperty("params", "count=countSql"); 46 | properties.setProperty("pageSizeZero", "true");//分页尺寸为0时查询所有纪录不再执行分页 47 | pageHelper.setProperties(properties); 48 | 49 | //添加插件 50 | bean.setPlugins(new Interceptor[]{pageHelper}); 51 | 52 | //添加XML目录 53 | ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 54 | bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); 55 | return bean.getObject(); 56 | } 57 | 58 | @Configuration 59 | @AutoConfigureAfter(MybatisConfigurer.class) 60 | public static class MyBatisMapperScannerConfigurer { 61 | 62 | @Bean 63 | public MapperScannerConfigurer mapperScannerConfigurer() { 64 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 65 | mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean"); 66 | mapperScannerConfigurer.setBasePackage(ProjectConstant.MAPPER_PACKAGE); 67 | //配置通用mappers 68 | Properties properties = new Properties(); 69 | properties.setProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE); 70 | properties.setProperty("notEmpty", "false"); 71 | properties.setProperty("IDENTITY", "MYSQL"); 72 | mapperScannerConfigurer.setProperties(properties); 73 | return mapperScannerConfigurer; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/conf/ProjectConstant.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.conf; 2 | 3 | /** 4 | * 项目常量 5 | */ 6 | public final class ProjectConstant { 7 | public static final String BASE_PACKAGE = "com.rogge.command";//项目基础包名称,根据自己公司的项目修改 8 | public static final String COMMON_PACKAGE = "com.rogge.common";//项目基础包名称,根据自己公司的项目修改 9 | 10 | public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model";//Model所在包 11 | public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".mapper";//Mapper所在包 12 | public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//Service所在包 13 | public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//ServiceImpl所在包 14 | public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web";//Controller所在包 15 | 16 | public static final String MAPPER_INTERFACE_REFERENCE = COMMON_PACKAGE + ".core.Mapper";//Mapper插件基础接口的完全限定名 17 | } 18 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/conf/WebMvcConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.conf; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.SerializerFeature; 5 | import com.alibaba.fastjson.support.config.FastJsonConfig; 6 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4; 7 | import com.rogge.common.core.ApiResponse; 8 | import com.rogge.common.core.ResponseCode; 9 | import com.rogge.common.core.ServiceException; 10 | import org.apache.ibatis.exceptions.TooManyResultsException; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.http.converter.HttpMessageConverter; 15 | import org.springframework.web.method.HandlerMethod; 16 | import org.springframework.web.servlet.HandlerExceptionResolver; 17 | import org.springframework.web.servlet.ModelAndView; 18 | import org.springframework.web.servlet.NoHandlerFoundException; 19 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 20 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 21 | 22 | import javax.servlet.ServletException; 23 | import javax.servlet.http.HttpServletRequest; 24 | import javax.servlet.http.HttpServletResponse; 25 | import java.io.IOException; 26 | import java.nio.charset.Charset; 27 | import java.util.List; 28 | 29 | /** 30 | * [Description] 31 | *

32 | * [How to use] 33 | *

34 | * [Tips] 35 | * 36 | * @author Created by Rogge on 2017/10/6 0006. 37 | * @since 1.0.0 38 | */ 39 | @Configuration 40 | public class WebMvcConfigurer extends WebMvcConfigurerAdapter { 41 | private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class); 42 | 43 | //使用阿里 FastJson 作为JSON MessageConverter 44 | @Override 45 | public void configureMessageConverters(List> converters) { 46 | FastJsonHttpMessageConverter4 converter = new FastJsonHttpMessageConverter4(); 47 | FastJsonConfig config = new FastJsonConfig(); 48 | config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,//保留空的字段 49 | SerializerFeature.WriteNullStringAsEmpty,//String null -> "" 50 | SerializerFeature.WriteEnumUsingToString,//使枚举返回ordinal 51 | SerializerFeature.WriteNullNumberAsZero);//Number null -> 0 52 | converter.setFastJsonConfig(config); 53 | converter.setDefaultCharset(Charset.forName("UTF-8")); 54 | converters.add(converter); 55 | } 56 | 57 | //统一异常处理 58 | @Override 59 | public void configureHandlerExceptionResolvers(List exceptionResolvers) { 60 | exceptionResolvers.add(new HandlerExceptionResolver() { 61 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { 62 | ApiResponse lApiResponse = new ApiResponse(); 63 | if (e instanceof ServiceException) {//业务失败的异常,如“账号或密码错误” 64 | lApiResponse.setCode(ResponseCode.Base.ERROR); 65 | lApiResponse.setMsg(e.getMessage()); 66 | logger.info(e.getMessage()); 67 | } else if (e instanceof NoHandlerFoundException) { 68 | lApiResponse.setCode(ResponseCode.Base.API_NO_EXISTS); 69 | lApiResponse.setMsg("接口 [" + request.getRequestURI() + "] 不存在"); 70 | } else if (e instanceof ServletException) { 71 | lApiResponse.setCode(ResponseCode.Base.ERROR); 72 | lApiResponse.setMsg(e.getMessage()); 73 | } else if (e.getCause() instanceof TooManyResultsException) { 74 | lApiResponse = ApiResponse.creatFail(ResponseCode.Base.TOO_MANY_EXCEP); 75 | } else { 76 | lApiResponse.setCode(ResponseCode.Base.API_ERR); 77 | lApiResponse.setMsg("接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员"); 78 | String message; 79 | if (handler instanceof HandlerMethod) { 80 | HandlerMethod handlerMethod = (HandlerMethod) handler; 81 | message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s", 82 | request.getRequestURI(), 83 | handlerMethod.getBean().getClass().getName(), 84 | handlerMethod.getMethod().getName(), 85 | e.getMessage()); 86 | } else { 87 | message = e.getMessage(); 88 | } 89 | logger.error(message, e); 90 | } 91 | responseResult(response, lApiResponse); 92 | return new ModelAndView(); 93 | } 94 | 95 | }); 96 | } 97 | 98 | //解决跨域问题 99 | @Override 100 | public void addCorsMappings(CorsRegistry registry) { 101 | //registry.addMapping("/**"); 102 | } 103 | 104 | private void responseResult(HttpServletResponse response, ApiResponse apiResponse) { 105 | response.setCharacterEncoding("UTF-8"); 106 | response.setHeader("Content-type", "application/json;charset=UTF-8"); 107 | response.setStatus(200); 108 | try { 109 | response.getWriter().write(JSON.toJSONString(apiResponse, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteEnumUsingToString)); 110 | } catch (IOException ex) { 111 | logger.error(ex.getMessage()); 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/mapper/CommandContentMapper.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.mapper; 2 | 3 | import com.rogge.command.model.CommandContent; 4 | import com.rogge.command.model.vo.CommentVO; 5 | import com.rogge.common.core.Mapper; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | 10 | @Repository 11 | public interface CommandContentMapper extends Mapper { 12 | List selectLeftJoinCommand(); 13 | } -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/model/CommandContent.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.model; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "command_content") 6 | public class CommandContent { 7 | /** 8 | * 主键 9 | */ 10 | @Id 11 | @Column(name = "ID") 12 | @GeneratedValue(strategy = GenerationType.IDENTITY) 13 | private Integer id; 14 | 15 | /** 16 | * 指令内容 17 | */ 18 | @Column(name = "CONTENT") 19 | private String content; 20 | 21 | /** 22 | * 指令主键 23 | */ 24 | @Column(name = "COMMAND_ID") 25 | private Integer commandId; 26 | 27 | /** 28 | * 获取主键 29 | * 30 | * @return ID - 主键 31 | */ 32 | public Integer getId() { 33 | return id; 34 | } 35 | 36 | /** 37 | * 设置主键 38 | * 39 | * @param id 主键 40 | */ 41 | public void setId(Integer id) { 42 | this.id = id; 43 | } 44 | 45 | /** 46 | * 获取指令内容 47 | * 48 | * @return CONTENT - 指令内容 49 | */ 50 | public String getContent() { 51 | return content; 52 | } 53 | 54 | /** 55 | * 设置指令内容 56 | * 57 | * @param content 指令内容 58 | */ 59 | public void setContent(String content) { 60 | this.content = content; 61 | } 62 | 63 | /** 64 | * 获取指令主键 65 | * 66 | * @return COMMAND_ID - 指令主键 67 | */ 68 | public Integer getCommandId() { 69 | return commandId; 70 | } 71 | 72 | /** 73 | * 设置指令主键 74 | * 75 | * @param commandId 指令主键 76 | */ 77 | public void setCommandId(Integer commandId) { 78 | this.commandId = commandId; 79 | } 80 | } -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/model/User.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.model; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import java.util.Date; 8 | 9 | public class User { 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer id; 13 | 14 | private String username; 15 | 16 | private String password; 17 | 18 | @Column(name = "nick_name") 19 | private String nickName; 20 | 21 | private Integer sex; 22 | 23 | @Column(name = "register_date") 24 | private Date registerDate; 25 | 26 | private String email; 27 | 28 | @Column(name = "pass_word") 29 | private String passWord; 30 | 31 | @Column(name = "reg_time") 32 | private String regTime; 33 | 34 | @Column(name = "user_name") 35 | private String userName; 36 | 37 | /** 38 | * @return id 39 | */ 40 | public Integer getId() { 41 | return id; 42 | } 43 | 44 | /** 45 | * @param id 46 | */ 47 | public void setId(Integer id) { 48 | this.id = id; 49 | } 50 | 51 | /** 52 | * @return username 53 | */ 54 | public String getUsername() { 55 | return username; 56 | } 57 | 58 | /** 59 | * @param username 60 | */ 61 | public void setUsername(String username) { 62 | this.username = username; 63 | } 64 | 65 | /** 66 | * @return password 67 | */ 68 | public String getPassword() { 69 | return password; 70 | } 71 | 72 | /** 73 | * @param password 74 | */ 75 | public void setPassword(String password) { 76 | this.password = password; 77 | } 78 | 79 | /** 80 | * @return nick_name 81 | */ 82 | public String getNickName() { 83 | return nickName; 84 | } 85 | 86 | /** 87 | * @param nickName 88 | */ 89 | public void setNickName(String nickName) { 90 | this.nickName = nickName; 91 | } 92 | 93 | /** 94 | * @return sex 95 | */ 96 | public Integer getSex() { 97 | return sex; 98 | } 99 | 100 | /** 101 | * @param sex 102 | */ 103 | public void setSex(Integer sex) { 104 | this.sex = sex; 105 | } 106 | 107 | /** 108 | * @return register_date 109 | */ 110 | public Date getRegisterDate() { 111 | return registerDate; 112 | } 113 | 114 | /** 115 | * @param registerDate 116 | */ 117 | public void setRegisterDate(Date registerDate) { 118 | this.registerDate = registerDate; 119 | } 120 | 121 | /** 122 | * @return email 123 | */ 124 | public String getEmail() { 125 | return email; 126 | } 127 | 128 | /** 129 | * @param email 130 | */ 131 | public void setEmail(String email) { 132 | this.email = email; 133 | } 134 | 135 | /** 136 | * @return pass_word 137 | */ 138 | public String getPassWord() { 139 | return passWord; 140 | } 141 | 142 | /** 143 | * @param passWord 144 | */ 145 | public void setPassWord(String passWord) { 146 | this.passWord = passWord; 147 | } 148 | 149 | /** 150 | * @return reg_time 151 | */ 152 | public String getRegTime() { 153 | return regTime; 154 | } 155 | 156 | /** 157 | * @param regTime 158 | */ 159 | public void setRegTime(String regTime) { 160 | this.regTime = regTime; 161 | } 162 | 163 | /** 164 | * @return user_name 165 | */ 166 | public String getUserName() { 167 | return userName; 168 | } 169 | 170 | /** 171 | * @param userName 172 | */ 173 | public void setUserName(String userName) { 174 | this.userName = userName; 175 | } 176 | } -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/model/vo/CommentVO.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.model.vo; 2 | 3 | 4 | import com.rogge.command.model.CommandContent; 5 | 6 | /** 7 | * [Description] 8 | *

9 | * [How to use] 10 | *

11 | * [Tips] 12 | * 13 | * @author Created by Rogge on 2017/10/6 0006. 14 | * @since 1.0.0 15 | */ 16 | public class CommentVO extends CommandContent { 17 | private String name; 18 | private String description; 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | public String getDescription() { 29 | return description; 30 | } 31 | 32 | public void setDescription(String description) { 33 | this.description = description; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "CommentVO{" + 39 | "name='" + name + '\'' + 40 | ", description='" + description + '\'' + 41 | '}'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/service/CommandContentService.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.service; 2 | 3 | 4 | import com.rogge.command.model.CommandContent; 5 | import com.rogge.command.model.vo.CommentVO; 6 | import com.rogge.common.core.Service; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * [Description] 12 | *

13 | * [How to use] 14 | *

15 | * [Tips] 16 | * 17 | * @author Created by Rogge on 2017/10/06 18 | * @since 1.0.0 19 | */ 20 | public interface CommandContentService extends Service { 21 | List getCommandLeftJoin(); 22 | } 23 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/service/impl/CommandContentServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.service.impl; 2 | 3 | import com.rogge.command.mapper.CommandContentMapper; 4 | import com.rogge.command.model.CommandContent; 5 | import com.rogge.command.model.vo.CommentVO; 6 | import com.rogge.command.service.CommandContentService; 7 | import com.rogge.common.core.AbstractService; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import javax.annotation.Resource; 12 | import java.util.List; 13 | 14 | 15 | /** 16 | * [Description] 17 | *

18 | * [How to use] 19 | *

20 | * [Tips] 21 | * 22 | * @author Created by Rogge on 2017/10/06 23 | * @since 1.0.0 24 | */ 25 | @Service 26 | @Transactional 27 | public class CommandContentServiceImpl extends AbstractService implements CommandContentService { 28 | @Resource 29 | private CommandContentMapper commandContentMapper; 30 | 31 | @Override 32 | public List getCommandLeftJoin() { 33 | return commandContentMapper.selectLeftJoinCommand(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /command-module/src/main/java/com/rogge/command/web/CommandContentController.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command.web; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.rogge.command.model.CommandContent; 6 | import com.rogge.command.model.vo.CommentVO; 7 | import com.rogge.command.service.CommandContentService; 8 | import com.rogge.common.core.ApiResponse; 9 | import com.rogge.common.core.BaseController; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.cache.annotation.Cacheable; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import javax.annotation.Resource; 16 | import java.util.List; 17 | 18 | /** 19 | * [Description] 20 | *

21 | * [How to use] 22 | *

23 | * [Tips] 24 | * 25 | * @author Created by Rogge on 2017/10/06 26 | * @since 1.0.0 27 | */ 28 | @RestController 29 | public class CommandContentController extends BaseController { 30 | private final Logger logger = LoggerFactory.getLogger(CommandContentController.class); 31 | 32 | @Resource 33 | private CommandContentService commandContentService; 34 | 35 | @PostMapping("/add") 36 | public ApiResponse add(CommandContent commandContent) { 37 | commandContentService.save(commandContent); 38 | return ApiResponse.creatSuccess(); 39 | } 40 | 41 | @PostMapping("/delete") 42 | public ApiResponse delete(@RequestParam Integer id) { 43 | commandContentService.deleteById(id); 44 | return ApiResponse.creatSuccess(); 45 | } 46 | 47 | @PostMapping("/update") 48 | public ApiResponse update(CommandContent commandContent) { 49 | commandContentService.update(commandContent); 50 | return ApiResponse.creatSuccess(); 51 | } 52 | 53 | @PostMapping("/detail") 54 | public ApiResponse detail(@RequestParam Integer id) { 55 | CommandContent commandContent = commandContentService.findById(id); 56 | return ApiResponse.creatSuccess(commandContent); 57 | } 58 | 59 | @PostMapping("/list") 60 | public ApiResponse list(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer size) { 61 | PageHelper.startPage(page, size); 62 | List list = commandContentService.findAll(); 63 | PageInfo pageInfo = new PageInfo(list); 64 | return ApiResponse.creatSuccess(pageInfo); 65 | } 66 | 67 | @GetMapping("/cc/{id}") 68 | public ApiResponse getCommandContentByOther(@PathVariable("id") int id) { 69 | CommandContent lCommandContent = commandContentService.findBy("commandId", id); 70 | return ApiResponse.creatSuccess(lCommandContent); 71 | } 72 | 73 | @Cacheable(value = "get_join_list") 74 | @GetMapping("/getLeftJoin") 75 | public ApiResponse getLeftJoin() { 76 | List list = commandContentService.getCommandLeftJoin(); 77 | logger.info("这句话只会在缓存失效的时候才会出现"); 78 | return ApiResponse.creatSuccess(list); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /command-module/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8082 3 | 4 | spring: 5 | application: 6 | name: command-module 7 | datasource: 8 | type: com.alibaba.druid.pool.DruidDataSource 9 | driver-class-name: com.mysql.jdbc.Driver 10 | url: jdbc:mysql://127.0.0.1:3306/rogge 11 | username: root 12 | password: 123456 13 | 14 | output: 15 | ansi: 16 | enabled: always #多彩log 17 | 18 | logging: 19 | level: 20 | com.rogge: debug 21 | file: ./logs/cm.log 22 | root: info 23 | 24 | eureka: 25 | client: 26 | serviceUrl: 27 | defaultZone: http://localhost:8089/eureka/ 28 | instance: 29 | preferIpAddress: true 30 | instance-id: ${spring.application.name}:${server.port} -------------------------------------------------------------------------------- /command-module/src/main/resources/mapper/CommandContentMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 22 | 23 | -------------------------------------------------------------------------------- /command-module/src/test/java/com/rogge/command/CmApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.rogge.command; 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 CmApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /common-module/.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/ -------------------------------------------------------------------------------- /common-module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.rogge.common 7 | common-module 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | common-module 12 | Demo project for Spring Boot 13 | 14 | 15 | com.rogge 16 | scloud 17 | 0.0.1-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | org.springframework.session 29 | spring-session-data-redis 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-maven-plugin 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/CommonModuleApplication.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CommonModuleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(CommonModuleApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/Constant.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common; 2 | 3 | public class Constant { 4 | 5 | /** 平台用户id **/ 6 | public static final long PLATFORM_USER_ID = 1; 7 | 8 | /** 存放当前会话语言 key **/ 9 | public static final String CURRENT_LANGUAGE = "CURRENT-LANGUAGE"; 10 | 11 | /** 存放当前会话微信登录openId **/ 12 | public static final String WEIXIN_OPENID = "WEIXIN-OPENID"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/annotation/Description.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 类、方法等描述 7 | * 8 | * @author droxy 9 | * 10 | */ 11 | @Target({ ElementType.TYPE, ElementType.METHOD }) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface Description { 15 | 16 | /** 17 | * 描述说明 18 | * 19 | * @return 20 | */ 21 | String value(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/conf/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.conf; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.cache.CacheManager; 7 | import org.springframework.cache.annotation.CachingConfigurerSupport; 8 | import org.springframework.cache.annotation.EnableCaching; 9 | import org.springframework.cache.interceptor.KeyGenerator; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.data.redis.cache.RedisCacheManager; 13 | import org.springframework.data.redis.connection.RedisConnectionFactory; 14 | import org.springframework.data.redis.core.RedisTemplate; 15 | import org.springframework.data.redis.core.StringRedisTemplate; 16 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * [Description] 22 | *

23 | * [How to use] 24 | *

25 | * [Tips] 26 | * 27 | * @author Created by Rogge on 2017/10/6 0006. 28 | * @since 1.0.0 29 | */ 30 | @Configuration 31 | @EnableCaching 32 | public class RedisConfig extends CachingConfigurerSupport { 33 | 34 | @Bean 35 | public KeyGenerator keyGenerator() { 36 | return new KeyGenerator() { 37 | @Override 38 | public Object generate(Object target, Method method, Object... params) { 39 | StringBuilder sb = new StringBuilder(); 40 | sb.append(target.getClass().getName()); 41 | sb.append(method.getName()); 42 | for (Object obj : params) { 43 | sb.append(obj.toString()); 44 | } 45 | return sb.toString(); 46 | } 47 | }; 48 | } 49 | 50 | @SuppressWarnings("rawtypes") 51 | @Bean 52 | public CacheManager cacheManager(RedisTemplate redisTemplate) { 53 | RedisCacheManager rcm = new RedisCacheManager(redisTemplate); 54 | //设置缓存过期时间 55 | // TODO: 2017/11/5 0005 by Rogge 设置缓存时间 56 | rcm.setDefaultExpiration(10);//秒 57 | return rcm; 58 | } 59 | 60 | @Bean 61 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 62 | StringRedisTemplate template = new StringRedisTemplate(factory); 63 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 64 | ObjectMapper om = new ObjectMapper(); 65 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 66 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 67 | jackson2JsonRedisSerializer.setObjectMapper(om); 68 | template.setValueSerializer(jackson2JsonRedisSerializer); 69 | template.afterPropertiesSet(); 70 | return template; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/conf/SessionConfig.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.conf; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 5 | 6 | @Configuration 7 | @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60*60) 8 | public class SessionConfig { 9 | //EnableRedisHttpSession为设置session失效时间默认半小时 10 | } -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/conf/redis/OnlineUserInfo.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.conf.redis; 2 | 3 | import com.github.pagehelper.StringUtil; 4 | import com.rogge.common.model.SessionUser; 5 | import com.rogge.common.model.Visitor; 6 | import org.apache.commons.logging.Log; 7 | import org.apache.commons.logging.LogFactory; 8 | import org.springframework.beans.factory.InitializingBean; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.annotation.Resource; 12 | import javax.servlet.http.HttpSession; 13 | import java.util.*; 14 | 15 | /** 16 | * 在线用户信息管理 17 | * 18 | * @author droxy 19 | * 20 | */ 21 | @Component 22 | public class OnlineUserInfo implements InitializingBean { 23 | 24 | private Log logger = LogFactory.getLog(getClass()); 25 | 26 | @Resource 27 | private RedisDao redisDao; 28 | 29 | /** 用户登录列表 **/ 30 | public static final String ONLINE_USER_HASH = "ONLINE-USER-HASH"; 31 | 32 | /** 用户登录列表field + [动态userId] **/ 33 | public static final String ONLINE_USER_HASH_FIELD = "ONLINE-USER-"; 34 | 35 | public String getField(SessionUser sessionUser) { 36 | return ONLINE_USER_HASH_FIELD + sessionUser.getUserType() + "@" + sessionUser.getId(); 37 | } 38 | 39 | /** 40 | * 新增用户 41 | * 42 | * @param visitor 43 | */ 44 | public void add(HttpSession session, Visitor visitor) { 45 | SessionUser sessionUser = visitor.getSessionUser(); 46 | Visitor v; 47 | if ((v = redisDao.hGet(ONLINE_USER_HASH, getField(sessionUser), Visitor.class)) != null && !session.getId().equals(v.getSessionId())) { 48 | logger.warn(sessionUser.getUserType() + "用户 " + sessionUser.getId() + " 账号异地(" + visitor.getIp() + ")登录"); 49 | } 50 | redisDao.hSet(ONLINE_USER_HASH, getField(sessionUser), visitor); 51 | } 52 | 53 | /** 54 | * 移除用户 55 | * 56 | * @param sessionUser 57 | */ 58 | public void remove(SessionUser sessionUser) { 59 | Visitor visitor = redisDao.hGet(ONLINE_USER_HASH, getField(sessionUser), Visitor.class); 60 | if (visitor != null && visitor.getSessionId() != null) { 61 | redisDao.hDel(ONLINE_USER_HASH, getField(sessionUser)); 62 | logger.debug(sessionUser.getUserType() + "用户(" + sessionUser.getId() + ")下线"); 63 | } 64 | } 65 | 66 | /** 67 | * 获取用户 68 | * 69 | * @param sessionUser 70 | */ 71 | public Visitor get(SessionUser sessionUser) { 72 | return redisDao.hGet(ONLINE_USER_HASH, getField(sessionUser), Visitor.class); 73 | } 74 | 75 | /** 76 | * 获取在线用户列表 77 | * 78 | * @return 79 | */ 80 | public List getList() { 81 | List visitors = redisDao.hVals(ONLINE_USER_HASH, Visitor.class); 82 | Collections.sort(visitors, new Comparator() { 83 | public int compare(Visitor o1, Visitor o2) { 84 | return (o2.getLoginDate().getTime() - o1.getLoginDate().getTime()) < 0 ? -1 : 1; 85 | } 86 | }); 87 | return visitors; 88 | } 89 | 90 | /** 91 | * 根据条件获取在线用户列表 92 | * 93 | * @return 94 | */ 95 | public List getList(String name) { 96 | List list = getList(); 97 | // 过滤条件 98 | if (!StringUtil.isEmpty(name)) { 99 | List _list = new ArrayList(list); 100 | Iterator iterator = _list.iterator(); 101 | while (iterator.hasNext()) { 102 | Visitor v = iterator.next(); 103 | SessionUser sessionUser = v.getSessionUser(); 104 | if (!sessionUser.getUsername().contains(name)) { 105 | iterator.remove(); 106 | } 107 | 108 | } 109 | list = _list; 110 | } 111 | return list; 112 | } 113 | 114 | public void afterPropertiesSet() throws Exception { 115 | new Thread() { 116 | public void run() { 117 | clear(); 118 | } 119 | }.start(); 120 | } 121 | 122 | private void clear() { 123 | 124 | // 清理已过期失效用户 125 | while (true) { 126 | List visitors = getList(); 127 | if (visitors != null) { 128 | Iterator iterator = visitors.iterator(); 129 | while (iterator.hasNext()) { 130 | Visitor visitor = iterator.next(); 131 | SessionUser sessionUser = visitor.getSessionUser(); 132 | long gap = new Date().getTime() - visitor.getLoginDate().getTime(); 133 | long unit = 1800 * 1000; 134 | if (gap > unit * 5) { 135 | remove(sessionUser); 136 | iterator.remove(); 137 | } 138 | } 139 | } 140 | try { 141 | Thread.sleep(30 * 60 * 1000);// 30分钟检查一次 142 | } catch (InterruptedException e) { 143 | e.printStackTrace(); 144 | } 145 | } 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/conf/redis/RedisDao.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.conf.redis; 2 | 3 | import org.springframework.dao.DataAccessException; 4 | import org.springframework.data.redis.connection.RedisConnection; 5 | import org.springframework.data.redis.core.RedisCallback; 6 | import org.springframework.data.redis.core.RedisTemplate; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.annotation.Resource; 10 | import java.io.Serializable; 11 | import java.util.ArrayList; 12 | import java.util.HashSet; 13 | import java.util.List; 14 | import java.util.Set; 15 | 16 | @Component 17 | public class RedisDao { 18 | 19 | @Resource 20 | private RedisTemplate redisTemplate; 21 | 22 | /** 23 | * 发送频道消息 24 | */ 25 | public void sendChannelMessage(String channel, Serializable message) { 26 | redisTemplate.convertAndSend(channel, message); 27 | } 28 | 29 | /** 30 | * 查询key是否存在 31 | * 32 | * @param key 33 | * @return 34 | */ 35 | public Boolean exists(final Serializable key) { 36 | return redisTemplate.execute(new RedisCallback() { 37 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 38 | return connection.exists(RedisSerializer.serialize(key)); 39 | } 40 | }); 41 | } 42 | 43 | /** 44 | * 删除key 45 | * 46 | * @param keys 47 | * @return 48 | */ 49 | public Long del(final Serializable... keys) { 50 | return redisTemplate.execute(new RedisCallback() { 51 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 52 | byte[][] ks = new byte[keys.length][]; 53 | for (int i = 0; i < keys.length; i++) { 54 | ks[i] = RedisSerializer.serialize(keys[i]); 55 | } 56 | return connection.del(ks); 57 | } 58 | }); 59 | } 60 | 61 | /** 62 | * 设置key过期时间 63 | * 64 | * @param key 65 | * @param seconds 66 | * @return 67 | */ 68 | public Boolean expire(final Serializable key, final long seconds) { 69 | return redisTemplate.execute(new RedisCallback() { 70 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 71 | return connection.expire(RedisSerializer.serialize(key), seconds); 72 | } 73 | }); 74 | } 75 | 76 | /** 77 | * 查询key过期时间 78 | * 79 | * @param key 80 | * @return 81 | */ 82 | public Long ttl(final Serializable key) { 83 | return redisTemplate.execute(new RedisCallback() { 84 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 85 | return connection.ttl(RedisSerializer.serialize(key)); 86 | } 87 | }); 88 | } 89 | 90 | /** 91 | * 保存值 92 | * 93 | * @param key 94 | * @param value 95 | */ 96 | public void set(final Serializable key, final Serializable value) { 97 | redisTemplate.execute(new RedisCallback() { 98 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 99 | byte[] k = RedisSerializer.serialize(key); 100 | byte[] v = RedisSerializer.serialize(value); 101 | connection.set(k, v); 102 | return true; 103 | } 104 | }); 105 | } 106 | 107 | /** 108 | * 获取值 109 | */ 110 | public T get(final Serializable key, final Class clazz) { 111 | return redisTemplate.execute(new RedisCallback() { 112 | public T doInRedis(RedisConnection connection) throws DataAccessException { 113 | byte[] k = RedisSerializer.serialize(key); 114 | byte[] result = connection.get(k); 115 | return RedisSerializer.deserialize(result, clazz); 116 | } 117 | }); 118 | } 119 | 120 | /** 121 | * 原子加1 122 | */ 123 | public Long incr(final Serializable key) { 124 | return redisTemplate.execute(new RedisCallback() { 125 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 126 | byte[] k = RedisSerializer.serialize(key); 127 | return connection.incr(k); 128 | } 129 | }); 130 | } 131 | 132 | /** 133 | * 原子减1 134 | */ 135 | public Long decr(final Serializable key) { 136 | return redisTemplate.execute(new RedisCallback() { 137 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 138 | byte[] k = RedisSerializer.serialize(key); 139 | return connection.decr(k); 140 | } 141 | }); 142 | } 143 | 144 | /** 145 | * 向Set集合添加N项 146 | */ 147 | public Long sAdd(final Serializable key, final Serializable... values) { 148 | return redisTemplate.execute(new RedisCallback() { 149 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 150 | byte[] k = RedisSerializer.serialize(key); 151 | byte[][] vs = new byte[values.length][]; 152 | for (int i = 0; i < values.length; i++) { 153 | vs[i] = RedisSerializer.serialize(values[i]); 154 | } 155 | return connection.sAdd(k, vs); 156 | } 157 | }); 158 | } 159 | 160 | /** 161 | * 统计Set集合多少项 162 | * 163 | * @param key 164 | * @return 165 | */ 166 | public Long sCard(final Serializable key) { 167 | return redisTemplate.execute(new RedisCallback() { 168 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 169 | byte[] k = RedisSerializer.serialize(key); 170 | return connection.sCard(k); 171 | } 172 | }); 173 | } 174 | 175 | /** 176 | * 判断Set集合中是否存在某项 177 | * 178 | * @param key 179 | * @param value 180 | * @return 181 | */ 182 | public Boolean sIsMember(final Serializable key, final Serializable value) { 183 | return redisTemplate.execute(new RedisCallback() { 184 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 185 | byte[] k = RedisSerializer.serialize(key); 186 | byte[] v = RedisSerializer.serialize(value); 187 | return connection.sIsMember(k, v); 188 | } 189 | }); 190 | } 191 | 192 | /** 193 | * 获取Set集合所有项值 194 | * 195 | * @param key 196 | * @param clazz 197 | * @return 198 | */ 199 | public Set sMembers(final Serializable key, final Class clazz) { 200 | return redisTemplate.execute(new RedisCallback>() { 201 | public Set doInRedis(RedisConnection connection) throws DataAccessException { 202 | byte[] k = RedisSerializer.serialize(key); 203 | Set sets = connection.sMembers(k); 204 | Set result = new HashSet(); 205 | if (sets != null && sets.size() > 0) { 206 | for (byte[] bs : sets) { 207 | result.add(RedisSerializer.deserialize(bs, clazz)); 208 | } 209 | } 210 | return result; 211 | } 212 | }); 213 | } 214 | 215 | /** 216 | * 删除Set集合中的N项 217 | * 218 | * @param key 219 | * @param values 220 | * @return 221 | */ 222 | public Long sRem(final Serializable key, final Serializable... values) { 223 | return redisTemplate.execute(new RedisCallback() { 224 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 225 | byte[] k = RedisSerializer.serialize(key); 226 | byte[][] vs = new byte[values.length][]; 227 | for (int i = 0; i < values.length; i++) { 228 | vs[i] = RedisSerializer.serialize(values[i]); 229 | } 230 | return connection.sRem(k, vs); 231 | } 232 | }); 233 | } 234 | 235 | /** 236 | * 向SortSet集合添加一项 237 | * 238 | * @param key 239 | * @param value 240 | * @return 241 | */ 242 | public Boolean zAdd(final Serializable key, final double score, final Serializable value) { 243 | return redisTemplate.execute(new RedisCallback() { 244 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 245 | byte[] k = RedisSerializer.serialize(key); 246 | byte[] v = RedisSerializer.serialize(value); 247 | return connection.zAdd(k, score, v); 248 | } 249 | }); 250 | } 251 | 252 | /** 253 | * 统计SortSet集合多少项 254 | * 255 | * @param key 256 | * @return 257 | */ 258 | public Long zCard(final Serializable key) { 259 | return redisTemplate.execute(new RedisCallback() { 260 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 261 | byte[] k = RedisSerializer.serialize(key); 262 | return connection.zCard(k); 263 | } 264 | }); 265 | } 266 | 267 | /** 268 | * 删除SortSet集合中的N项 269 | * 270 | * @param key 271 | * @param values 272 | * @return 273 | */ 274 | public Long zRem(final Serializable key, final Serializable... values) { 275 | return redisTemplate.execute(new RedisCallback() { 276 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 277 | byte[] k = RedisSerializer.serialize(key); 278 | byte[][] vs = new byte[values.length][]; 279 | for (int i = 0; i < values.length; i++) { 280 | vs[i] = RedisSerializer.serialize(values[i]); 281 | } 282 | return connection.zRem(k, vs); 283 | } 284 | }); 285 | } 286 | 287 | /** 288 | * 设置hash 289 | * 290 | * @param key 291 | * @param field 292 | * @param value 293 | * @return 294 | */ 295 | public Boolean hSet(final Serializable key, final Serializable field, final Serializable value) { 296 | return redisTemplate.execute(new RedisCallback() { 297 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 298 | byte[] k = RedisSerializer.serialize(key); 299 | byte[] f = RedisSerializer.serialize(field); 300 | byte[] v = RedisSerializer.serialize(value); 301 | return connection.hSet(k, f, v); 302 | } 303 | }); 304 | } 305 | 306 | /** 307 | * 删除hash下N个field 308 | * 309 | * @param key 310 | * @param fields 311 | * @return 312 | */ 313 | public Long hDel(final Serializable key, final Serializable... fields) { 314 | return redisTemplate.execute(new RedisCallback() { 315 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 316 | byte[] k = RedisSerializer.serialize(key); 317 | byte[][] fs = new byte[fields.length][]; 318 | for (int i = 0; i < fields.length; i++) { 319 | fs[i] = RedisSerializer.serialize(fields[i]); 320 | } 321 | return connection.hDel(k, fs); 322 | } 323 | }); 324 | } 325 | 326 | /** 327 | * 判断hash中是否存在filed 328 | * 329 | * @param key 330 | * @param field 331 | * @return 332 | */ 333 | public Boolean hExists(final Serializable key, final Serializable field) { 334 | return redisTemplate.execute(new RedisCallback() { 335 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 336 | byte[] k = RedisSerializer.serialize(key); 337 | byte[] f = RedisSerializer.serialize(field); 338 | return connection.hExists(k, f); 339 | } 340 | }); 341 | } 342 | 343 | /** 344 | * 获取hash中field值 345 | * 346 | * @param key 347 | * @param field 348 | * @param clazz 349 | * @return 350 | */ 351 | public T hGet(final Serializable key, final Serializable field, final Class clazz) { 352 | return redisTemplate.execute(new RedisCallback() { 353 | public T doInRedis(RedisConnection connection) throws DataAccessException { 354 | byte[] k = RedisSerializer.serialize(key); 355 | byte[] f = RedisSerializer.serialize(field); 356 | byte[] result = connection.hGet(k, f); 357 | return RedisSerializer.deserialize(result, clazz); 358 | } 359 | }); 360 | } 361 | 362 | /** 363 | * 获取hash所有key 364 | * 365 | * @param key 366 | * @param clazz 367 | * @return 368 | */ 369 | public Set hKeys(final Serializable key, final Class clazz) { 370 | return redisTemplate.execute(new RedisCallback>() { 371 | public Set doInRedis(RedisConnection connection) throws DataAccessException { 372 | byte[] k = RedisSerializer.serialize(key); 373 | Set result = connection.hKeys(k); 374 | Set sets = new HashSet(); 375 | if (result != null && result.size() > 0) { 376 | for (byte[] b : result) { 377 | T t = RedisSerializer.deserialize(b, clazz); 378 | sets.add(t); 379 | } 380 | } 381 | return sets; 382 | } 383 | }); 384 | } 385 | 386 | /** 387 | * 获取hash所有value 388 | * 389 | * @param key 390 | * @param clazz 391 | * @return 392 | */ 393 | public List hVals(final Serializable key, final Class clazz) { 394 | return redisTemplate.execute(new RedisCallback>() { 395 | public List doInRedis(RedisConnection connection) throws DataAccessException { 396 | byte[] k = RedisSerializer.serialize(key); 397 | List result = connection.hVals(k); 398 | List sets = new ArrayList(); 399 | if (result != null && result.size() > 0) { 400 | for (byte[] b : result) { 401 | T t = RedisSerializer.deserialize(b, clazz); 402 | sets.add(t); 403 | } 404 | } 405 | return sets; 406 | } 407 | }); 408 | } 409 | 410 | /** 411 | * 统计List长度 412 | * 413 | * @param key 414 | * @return 415 | */ 416 | public Long lLen(final Serializable key) { 417 | return redisTemplate.execute(new RedisCallback() { 418 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 419 | byte[] k = RedisSerializer.serialize(key); 420 | return connection.lLen(k); 421 | } 422 | }); 423 | } 424 | 425 | /** 426 | * 设置List项值 427 | * 428 | * @param key 429 | * @return 430 | */ 431 | public Boolean lSet(final Serializable key, final int index, final Serializable value) { 432 | return redisTemplate.execute(new RedisCallback() { 433 | public Boolean doInRedis(RedisConnection connection) throws DataAccessException { 434 | byte[] k = RedisSerializer.serialize(key); 435 | byte[] v = RedisSerializer.serialize(value); 436 | connection.lSet(k, index, v); 437 | return true; 438 | } 439 | }); 440 | } 441 | 442 | /** 443 | * 获取List项值 444 | * 445 | * @param key 446 | * @return 447 | */ 448 | public T lIndex(final Serializable key, final int index, final Class clazz) { 449 | return redisTemplate.execute(new RedisCallback() { 450 | public T doInRedis(RedisConnection connection) throws DataAccessException { 451 | byte[] k = RedisSerializer.serialize(key); 452 | byte[] result = connection.lIndex(k, index); 453 | return RedisSerializer.deserialize(result, clazz); 454 | } 455 | }); 456 | } 457 | 458 | /** 459 | * 移除List第一项 460 | * 461 | * @param key 462 | * @return 463 | */ 464 | public T lPop(final Serializable key, final Class clazz) { 465 | return redisTemplate.execute(new RedisCallback() { 466 | public T doInRedis(RedisConnection connection) throws DataAccessException { 467 | byte[] k = RedisSerializer.serialize(key); 468 | byte[] result = connection.lPop(k); 469 | return RedisSerializer.deserialize(result, clazz); 470 | } 471 | }); 472 | } 473 | 474 | /** 475 | * 移除List最后一项 476 | * 477 | * @param key 478 | * @return 479 | */ 480 | public T rPop(final Serializable key, final Class clazz) { 481 | return redisTemplate.execute(new RedisCallback() { 482 | public T doInRedis(RedisConnection connection) throws DataAccessException { 483 | byte[] k = RedisSerializer.serialize(key); 484 | byte[] result = connection.rPop(k); 485 | return RedisSerializer.deserialize(result, clazz); 486 | } 487 | }); 488 | } 489 | 490 | /** 491 | * 向List头部追加N项 492 | * 493 | * @param key 494 | * @return 495 | */ 496 | public Long lPush(final Serializable key, final Serializable... values) { 497 | return redisTemplate.execute(new RedisCallback() { 498 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 499 | byte[] k = RedisSerializer.serialize(key); 500 | byte[][] vs = new byte[values.length][]; 501 | for (int i = 0; i < values.length; i++) { 502 | vs[i] = RedisSerializer.serialize(values[i]); 503 | } 504 | return connection.lPush(k, vs); 505 | } 506 | }); 507 | } 508 | 509 | /** 510 | * 向List尾部追加N项 511 | * 512 | * @param key 513 | * @return 514 | */ 515 | public Long rPush(final Serializable key, final Serializable... values) { 516 | return redisTemplate.execute(new RedisCallback() { 517 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 518 | byte[] k = RedisSerializer.serialize(key); 519 | byte[][] vs = new byte[values.length][]; 520 | for (int i = 0; i < values.length; i++) { 521 | vs[i] = RedisSerializer.serialize(values[i]); 522 | } 523 | return connection.rPush(k, vs); 524 | } 525 | }); 526 | } 527 | 528 | /** 529 | * 获取List集合范围记录 530 | * 531 | * @param key 532 | * @param start 533 | * 开始位置 534 | * @param end 535 | * 结束位置 536 | * @param clazz 537 | * @return 538 | */ 539 | 540 | public List lrange(final Serializable key, final int start, final int end, final Class clazz) { 541 | return redisTemplate.execute(new RedisCallback>() { 542 | public List doInRedis(RedisConnection connection) throws DataAccessException { 543 | byte[] k = RedisSerializer.serialize(key); 544 | List list = connection.lRange(k, start, end); 545 | List result = new ArrayList(); 546 | if (list != null && list.size() > 0) { 547 | for (byte[] bs : list) { 548 | result.add(RedisSerializer.deserialize(bs, clazz)); 549 | } 550 | } 551 | return result; 552 | } 553 | }); 554 | } 555 | 556 | /** 557 | * 删除List中的记录 558 | * 559 | * @param key 560 | * @param count 561 | * 要删除的数量,如果为负从尾部开始检查 562 | * @param value 563 | * @return 删除后List的长度 564 | */ 565 | public Long lRem(final Serializable key, final int count, final Serializable value) { 566 | return redisTemplate.execute(new RedisCallback() { 567 | public Long doInRedis(RedisConnection connection) throws DataAccessException { 568 | byte[] k = RedisSerializer.serialize(key); 569 | byte[] v = RedisSerializer.serialize(value); 570 | return connection.lRem(k, count, v); 571 | } 572 | }); 573 | } 574 | 575 | } 576 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/conf/redis/RedisSerializer.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.conf.redis; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | 6 | import java.io.*; 7 | import java.lang.reflect.Method; 8 | 9 | public class RedisSerializer { 10 | 11 | private static Log logger = LogFactory.getLog(RedisSerializer.class); 12 | 13 | public static final String CHARSET = "utf-8"; 14 | 15 | public static byte[] serialize(T t) throws RuntimeException { 16 | if (t == null) { 17 | return null; 18 | } 19 | byte[] bytes = null; 20 | try { 21 | if (t.getClass() == Integer.TYPE || t.getClass() == Integer.class 22 | || t.getClass() == Long.TYPE || t.getClass() == Long.class 23 | || t.getClass() == Short.TYPE || t.getClass() == Short.class 24 | || t.getClass() == Double.TYPE || t.getClass() == Double.class 25 | || t.getClass() == Float.TYPE || t.getClass() == Float.class 26 | || t.getClass() == Byte.TYPE || t.getClass() == Byte.class 27 | || t.getClass() == Character.TYPE || t.getClass() == Character.class 28 | || t.getClass() == Boolean.TYPE || t.getClass() == Boolean.class 29 | || t.getClass() == String.class) { 30 | bytes = (t + "").getBytes(CHARSET); 31 | } else { 32 | ByteArrayOutputStream baos = null; 33 | ObjectOutputStream oos = null; 34 | try { 35 | baos = new ByteArrayOutputStream(); 36 | oos = new ObjectOutputStream(baos); 37 | oos.writeObject(t); 38 | bytes = baos.toByteArray(); 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } finally { 42 | if (baos != null) { 43 | baos.close(); 44 | } 45 | if (oos != null) { 46 | oos.close(); 47 | } 48 | } 49 | } 50 | } catch (Exception e) { 51 | logger.error("序列化失败 " + e.getMessage(), e); 52 | // throw new NormalRuntimeException("序列化失败", e); 53 | } 54 | return bytes; 55 | } 56 | 57 | @SuppressWarnings("unchecked") 58 | public static T deserialize(byte[] bytes, Class clazz) throws RuntimeException { 59 | if (bytes == null || bytes.length <= 0) { 60 | return null; 61 | } 62 | try { 63 | if (clazz == Integer.TYPE || clazz == Integer.class 64 | || clazz == Long.TYPE || clazz == Long.class 65 | || clazz == Short.TYPE || clazz == Short.class 66 | || clazz == Double.TYPE || clazz == Double.class 67 | || clazz == Float.TYPE || clazz == Float.class 68 | || clazz == Byte.TYPE || clazz == Byte.class 69 | || clazz == Character.TYPE || clazz == Character.class 70 | || clazz == Boolean.TYPE || clazz == Boolean.class 71 | || clazz == String.class) { 72 | 73 | String s = null; 74 | 75 | s = new String(bytes, CHARSET); 76 | 77 | if (clazz == String.class) { 78 | return (T) s; 79 | } else if (clazz == Character.TYPE || clazz == Character.class) { 80 | Character c = s.charAt(0); 81 | return (T) c; 82 | } else { 83 | Method method = clazz.getMethod("valueOf", String.class); 84 | Object object = method.invoke(null, s); 85 | return (T) object; 86 | } 87 | } else { 88 | ByteArrayInputStream bais = null; 89 | ObjectInputStream ois = null; 90 | try { 91 | bais = new ByteArrayInputStream(bytes); 92 | ois = new ObjectInputStream(bais); 93 | Object object = ois.readObject(); 94 | return (T) object; 95 | } catch (Exception e) { 96 | logger.error("反序列化失败 " + e.getMessage(), e); 97 | // throw new NormalRuntimeException("反序列化失败", e); 98 | } finally { 99 | if (ois != null) { 100 | ois.close(); 101 | } 102 | if (bais != null) { 103 | bais.close(); 104 | } 105 | } 106 | } 107 | } catch (Exception e) { 108 | e.printStackTrace(); 109 | } 110 | return null; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/conf/redis/SessionUserInfo.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.conf.redis; 2 | 3 | import com.rogge.common.model.SessionUser; 4 | import com.rogge.common.model.Visitor; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.context.request.RequestContextHolder; 8 | import org.springframework.web.context.request.ServletRequestAttributes; 9 | import org.springframework.web.context.support.WebApplicationContextUtils; 10 | 11 | import javax.annotation.Resource; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpSession; 14 | 15 | /** 16 | * 存储会话用户信息管理 17 | * @author droxy 18 | */ 19 | @Component 20 | public class SessionUserInfo { 21 | 22 | @Resource 23 | private RedisDao redisDao; 24 | 25 | @Resource 26 | private OnlineUserInfo onlineUserInfo; 27 | 28 | /** 29 | * 获取用户存放在session会话中的id 30 | */ 31 | public String getSessionUserIdKey(String userType) { 32 | return "USER-ID-" + userType; 33 | } 34 | 35 | /** 36 | * 获取session会话存放在redis的key 37 | */ 38 | public String getSessionUserKey(String userType, int userId) { 39 | return "SESSION-USER:" + userType + ":" + userId; 40 | } 41 | 42 | /** 43 | * 存储用户信息到当前session 44 | */ 45 | public void setSessionUser(HttpSession session, SessionUser sessionUser, Visitor visitor, boolean store) { 46 | // session写id 47 | session.setAttribute(getSessionUserIdKey(sessionUser.getUserType()), sessionUser.getId()); 48 | // 写入redis 49 | setSessionUser(sessionUser); 50 | // 标记在线 51 | if (store) { 52 | onlineUserInfo.add(session, visitor); 53 | } 54 | } 55 | 56 | public void setSessionUser(HttpSession session, SessionUser sessionUser) { 57 | setSessionUser(session, sessionUser, null, false); 58 | } 59 | 60 | /** 61 | * 存储用户信息到指定用户id 62 | */ 63 | public void setSessionUser(SessionUser sessionUser) { 64 | // redis写内容 65 | redisDao.set(getSessionUserKey(sessionUser.getUserType(), sessionUser.getId()), sessionUser); 66 | // 设置redis过期(超过30分钟没操作手机自动失效) 67 | redisDao.expire(getSessionUserKey(sessionUser.getUserType(), sessionUser.getId()), 30 * 60); 68 | } 69 | 70 | /** 71 | * 获取用户类型 72 | */ 73 | private static String getUserType(Class clazz) { 74 | try { 75 | SessionUser sessionUser = clazz.newInstance(); 76 | return sessionUser.getUserType(); 77 | } catch (Exception e) { 78 | throw new RuntimeException(e); 79 | } 80 | } 81 | 82 | /** 83 | * 获取当前session会话用户信息 84 | */ 85 | public T getSessionUser(HttpSession session, Class clazz) { 86 | 87 | Integer userId = (Integer) session.getAttribute(getSessionUserIdKey(getUserType(clazz))); 88 | if (userId != null) { 89 | return redisDao.get(getSessionUserKey(getUserType(clazz), userId), clazz); 90 | } 91 | return null; 92 | } 93 | 94 | /** 95 | * 根据id获取用户信息 96 | */ 97 | public T getSessionUser(int userId, Class clazz) { 98 | if (userId != 0) { 99 | return redisDao.get(getSessionUserKey(getUserType(clazz), userId), clazz); 100 | } 101 | return null; 102 | } 103 | 104 | /** 105 | * 删除当前用户会话 106 | */ 107 | public void removeSessionUser(HttpSession session, Class clazz) { 108 | if (session == null) { 109 | return; 110 | } 111 | Integer userId = (Integer) session.getAttribute(getSessionUserIdKey(getUserType(clazz))); 112 | if (userId != 0) { 113 | SessionUser sessionUser = getSessionUser(session, clazz); 114 | if (sessionUser != null) { 115 | // 删除在线信息 116 | onlineUserInfo.remove(sessionUser); 117 | } 118 | redisDao.del(getSessionUserKey(getUserType(clazz), userId)); 119 | } 120 | session.removeAttribute(getSessionUserIdKey(getUserType(clazz))); 121 | 122 | } 123 | 124 | /** 125 | * 删除指定用户 126 | */ 127 | public void removeSessionUser(SessionUser sessionUser) { 128 | redisDao.del(getSessionUserKey(sessionUser.getUserType(), sessionUser.getId())); 129 | } 130 | 131 | /** 132 | * 获取当前会话 133 | */ 134 | public T getCurrentSessionUser(Class clazz) { 135 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 136 | return getSessionUser(request.getSession(), clazz); 137 | } 138 | 139 | /** 140 | * 获取当前会话(静态) 141 | */ 142 | public static T getSessionUser(Class clazz) { 143 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 144 | ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext()); 145 | SessionUserInfo sessionUserInfo = (SessionUserInfo) ctx.getBean("sessionUserInfo"); 146 | return sessionUserInfo.getSessionUser(request.getSession(), clazz); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/AbstractService.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | 4 | import org.apache.ibatis.exceptions.TooManyResultsException; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import tk.mybatis.mapper.entity.Condition; 7 | 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.ParameterizedType; 10 | import java.util.List; 11 | 12 | /** 13 | * 基于通用MyBatis Mapper插件的Service接口的实现 14 | */ 15 | public abstract class AbstractService implements Service { 16 | 17 | @Autowired 18 | protected Mapper mapper; 19 | 20 | private Class modelClass; // 当前泛型真实类型的Class 21 | 22 | public AbstractService() { 23 | ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); 24 | modelClass = (Class) pt.getActualTypeArguments()[0]; 25 | } 26 | 27 | public void save(T model) { 28 | mapper.insertSelective(model); 29 | } 30 | 31 | public void save(List models) { 32 | mapper.insertList(models); 33 | } 34 | 35 | public void deleteById(Integer id) { 36 | mapper.deleteByPrimaryKey(id); 37 | } 38 | 39 | public void deleteByIds(String ids) { 40 | mapper.deleteByIds(ids); 41 | } 42 | 43 | public void update(T model) { 44 | mapper.updateByPrimaryKeySelective(model); 45 | } 46 | 47 | public T findById(Integer id) { 48 | return mapper.selectByPrimaryKey(id); 49 | } 50 | 51 | @Override 52 | public T findBy(String fieldName, Object value) throws TooManyResultsException { 53 | try { 54 | T model = modelClass.newInstance(); 55 | Field field = modelClass.getDeclaredField(fieldName); 56 | field.setAccessible(true); 57 | field.set(model, value); 58 | return mapper.selectOne(model); 59 | } catch (ReflectiveOperationException e) { 60 | throw new ServiceException(e.getMessage(), e); 61 | } 62 | } 63 | 64 | public List findByIds(String ids) { 65 | return mapper.selectByIds(ids); 66 | } 67 | 68 | public List findByCondition(Condition condition) { 69 | return mapper.selectByCondition(condition); 70 | } 71 | 72 | public List findAll() { 73 | return mapper.selectAll(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/ApiResponse.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.rogge.common.model.LanguageEnum; 5 | import com.rogge.common.util.Util; 6 | 7 | import java.io.Serializable; 8 | import java.util.Map; 9 | 10 | /** 11 | * API结果返回对象 12 | * 13 | *

14 | * 注意:在Controller层调用才有国际化效果,否则只会取到中文 15 | *

16 | * 17 | * @author droxy 18 | * @date 2017年3月24日 上午10:30:03 19 | * 20 | */ 21 | public class ApiResponse implements Serializable { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private ResponseCode code = ResponseCode.Base.ERROR; 26 | private String msg; 27 | private Object data; 28 | 29 | public ApiResponse() { 30 | 31 | } 32 | 33 | public ApiResponse(ResponseCode code) { 34 | this(code, null); 35 | } 36 | 37 | public ApiResponse(ResponseCode code, String msg) { 38 | this(code, msg, null); 39 | } 40 | 41 | public ApiResponse(ResponseCode code, String msg, Object data) { 42 | this.code = code; 43 | this.msg = msg; 44 | this.data = data; 45 | } 46 | 47 | public static ApiResponse creatSuccess() { 48 | return creatSuccess((Object) null); 49 | } 50 | 51 | public static ApiResponse creatSuccess(String msg) { 52 | return new ApiResponse(ResponseCode.Base.SUCCESS, msg); 53 | } 54 | 55 | public static ApiResponse creatSuccess(Object data) { 56 | return creatSuccess(data, Util.getCurrentLanguage()); 57 | } 58 | 59 | public static ApiResponse creatSuccess(String msg, Object data) { 60 | return new ApiResponse(ResponseCode.Base.SUCCESS, msg, data); 61 | } 62 | 63 | public static ApiResponse creatSuccess(Object data, LanguageEnum language) { 64 | return new ApiResponse(ResponseCode.Base.SUCCESS, ResponseCode.Base.SUCCESS.getExplain(language), data); 65 | } 66 | 67 | public static ApiResponse creatFail(ResponseCode responseCode) { 68 | return creatFail(responseCode, Util.getCurrentLanguage()); 69 | } 70 | 71 | public static ApiResponse creatFail(ResponseCode responseCode, Map params) { 72 | return creatFail(responseCode, Util.getCurrentLanguage(), params); 73 | } 74 | 75 | public static ApiResponse creatFail(ResponseCode responseCode, LanguageEnum language) { 76 | return new ApiResponse(responseCode, responseCode.getExplain(language)); 77 | } 78 | 79 | public static ApiResponse creatFail(ResponseCode responseCode, LanguageEnum language, Map params) { 80 | return new ApiResponse(responseCode, Util.convertParam(responseCode.getExplain(language), params)); 81 | } 82 | 83 | public static ApiResponse getApiResponse(ServiceApiResponse serviceApiResponse) { 84 | return new ApiResponse(serviceApiResponse.getCode(), Util.convertParam(serviceApiResponse.getCode().getExplain(Util.getCurrentLanguage()), serviceApiResponse.getParams()), serviceApiResponse.getData()); 85 | } 86 | 87 | public String getMsg() { 88 | return msg; 89 | } 90 | 91 | public ResponseCode getCode() { 92 | return code; 93 | } 94 | 95 | public void setCode(ResponseCode code) { 96 | this.code = code; 97 | } 98 | 99 | public void setMsg(String msg) { 100 | this.msg = msg; 101 | } 102 | 103 | public Object getData() { 104 | return data; 105 | } 106 | 107 | public void setData(Object data) { 108 | this.data = data; 109 | } 110 | 111 | @Override 112 | public String toString() { 113 | return "ApiResponse [code=" + code + ", msg=" + msg + ", data=" + data + "]"; 114 | } 115 | 116 | /** 117 | * 生成请求结果Json 118 | */ 119 | public String toJson() { 120 | return JSON.toJSONString(this); 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/ApiResponseVO.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.rogge.common.model.LanguageEnum; 5 | import com.rogge.common.util.Util; 6 | 7 | import java.io.Serializable; 8 | import java.util.Map; 9 | 10 | /** 11 | * API结果返回对象 12 | * 13 | *

14 | * 注意:在Controller层调用才有国际化效果,否则只会取到中文 15 | *

16 | * 17 | * @author droxy 18 | * @date 2017年3月24日 上午10:30:03 19 | * 20 | */ 21 | public class ApiResponseVO implements Serializable { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private int code; 26 | private String msg; 27 | private Object data; 28 | 29 | public int getCode() { 30 | return code; 31 | } 32 | 33 | public void setCode(int code) { 34 | this.code = code; 35 | } 36 | 37 | public String getMsg() { 38 | return msg; 39 | } 40 | 41 | public void setMsg(String msg) { 42 | this.msg = msg; 43 | } 44 | 45 | public Object getData() { 46 | return data; 47 | } 48 | 49 | public void setData(Object data) { 50 | this.data = data; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | import com.rogge.common.conf.redis.RedisDao; 4 | import com.rogge.common.conf.redis.SessionUserInfo; 5 | import org.springframework.beans.propertyeditors.CustomDateEditor; 6 | import org.springframework.web.bind.WebDataBinder; 7 | import org.springframework.web.bind.annotation.InitBinder; 8 | 9 | import javax.annotation.Resource; 10 | import java.text.SimpleDateFormat; 11 | import java.util.Date; 12 | 13 | public class BaseController { 14 | 15 | protected static final String PAGE_SIZE = "10"; 16 | /** 17 | * 默认每页显示条数 18 | */ 19 | 20 | @Resource 21 | public RedisDao mRedisDao; 22 | @Resource 23 | public SessionUserInfo mSessionUserInfo; 24 | 25 | @InitBinder 26 | protected void initBinder(WebDataBinder binder) { 27 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 28 | dateFormat.setLenient(false); 29 | binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/Mapper.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | import tk.mybatis.mapper.common.BaseMapper; 4 | import tk.mybatis.mapper.common.ConditionMapper; 5 | import tk.mybatis.mapper.common.IdsMapper; 6 | import tk.mybatis.mapper.common.special.InsertListMapper; 7 | 8 | /** 9 | * 定制版MyBatis Mapper插件接口,如需其他接口参考官方文档自行添加。 10 | */ 11 | public interface Mapper 12 | extends 13 | BaseMapper, 14 | ConditionMapper, 15 | IdsMapper, 16 | InsertListMapper { 17 | } 18 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/ResponseCode.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | import com.rogge.common.annotation.Description; 4 | import com.rogge.common.model.LanguageEnum; 5 | 6 | /** 7 | * 返回码
8 | *
    9 | *
  • 可使用{@link #getCode()}获取Integer类型的状态码,或
  • 10 | *
  • 可使用{@link #getExplain(LanguageEnum language)}获取错误原因说明
  • 11 | *
  • 使用{@link #toString()}字符串类型的状态码
  • 12 | *
13 | * 本接口含有以下enum类: 14 | *
    15 | *
  • {@link Base}基础返回码,码段(0~99)
  • 16 | *
  • {@link Parameter}参数类,码段(110-199)
  • 17 | *
  • {@link LoginRegister}登录权限类,码段(310-399)
  • 18 | *

    19 | *

20 | * 21 | * @author Anty 22 | */ 23 | public interface ResponseCode { 24 | 25 | /** 26 | * @return 状态码 27 | */ 28 | int getCode(); 29 | 30 | /** 31 | * @return 状态码对应的解释。 32 | */ 33 | String getExplain(LanguageEnum language); 34 | 35 | /** 36 | * @return 将状态码转换为字符串返回。 37 | */ 38 | String toString(); 39 | 40 | /** 41 | * 基础返回码(0-99) 42 | */ 43 | @Description("基础返回码(0-99)") 44 | public enum Base implements ResponseCode { 45 | /** 46 | * 基础返回码--请求成功 47 | */ 48 | SUCCESS(0, "请求成功", "Success"), 49 | /** 50 | * 基础返回码--错误 51 | */ 52 | ERROR(1, "错误", "Error"), 53 | /** 54 | * 基础返回码--请求超时 55 | */ 56 | REQUEST_TIMEOUT(2, "请求超时", "Request timeout"), 57 | /** 58 | * 基础返回码--系统通讯异常 59 | */ 60 | NET_ERR(3, "系统通讯异常", "Net error"), 61 | /** 62 | * 基础返回码--接口不存在 63 | */ 64 | API_NO_EXISTS(4, "接口不存在", "API NO EXISTS"), 65 | /** 66 | * 基础返回码--接口异常 67 | */ 68 | API_ERR(5, "接口异常", "API error"), 69 | /** 70 | * 基础返回码--MybatisTooManyException 71 | */ 72 | TOO_MANY_EXCEP(6, "查询结果不唯一", "TOO MANY Exception"), 73 | /** 74 | * 基础返回码--系统错误 75 | */ 76 | SYSTEM_ERR(10, "系统繁忙,请稍候再试", "System is busy, please try again later"); 77 | 78 | private final Integer code; 79 | private String zhExplain; 80 | private String enExplain; 81 | 82 | private Base(int code) { 83 | this.code = code; 84 | } 85 | 86 | private Base(Integer code, String zhExplain) { 87 | this.code = code; 88 | this.zhExplain = zhExplain; 89 | } 90 | 91 | private Base(Integer code, String zhExplain, String enExplain) { 92 | this.code = code; 93 | this.zhExplain = zhExplain; 94 | this.enExplain = enExplain; 95 | } 96 | 97 | @Override 98 | public int getCode() { 99 | return code; 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return code.toString(); 105 | } 106 | 107 | @Override 108 | public String getExplain(LanguageEnum language) { 109 | if (language == LanguageEnum.zh_CN) { 110 | return zhExplain; 111 | } else { 112 | return enExplain; 113 | } 114 | } 115 | 116 | } 117 | 118 | /** 119 | * 请求参数错误提示返回码 120 | */ 121 | @Description("请求参数错误提示返回码(1xx)") 122 | public enum Parameter implements ResponseCode { 123 | /** 124 | * 返回码--传入参数类--参数为空 125 | */ 126 | NULL(101, "传入参数不能为空", "Incoming parameters cannot be empty"), 127 | /** 128 | * 返回码--传入参数类--无法解析 129 | */ 130 | CANNOT_PARSE(102, "传入参数无法解析", "Unable to parse the incoming parameters"), 131 | /** 132 | * 返回码--传入参数类--格式错误 133 | */ 134 | FORMAT_ERR(103, "传入参数格式错误", "Incoming parameters format error"), 135 | /** 136 | * 返回码--传入参数类--缺少必要参数 137 | */ 138 | LACK(104, "缺少必要参数", "Missing Parameters "), 139 | /** 140 | * 返回码--传入参数类--参数值不合法 141 | */ 142 | ILLEGAL(105, "传入参数值不合法", "Incoming parameters values are not legal"), 143 | /** 144 | * 返回码--传入参数类--其他错误 145 | */ 146 | OTHERS(199, "参数错误", "Parameters error"); 147 | 148 | private final Integer code; 149 | private String zhExplain; 150 | private String enExplain; 151 | 152 | private Parameter(int code) { 153 | this.code = code; 154 | } 155 | 156 | private Parameter(Integer code, String zhExplain) { 157 | this.code = code; 158 | this.zhExplain = zhExplain; 159 | } 160 | 161 | private Parameter(Integer code, String zhExplain, String enExplain) { 162 | this.code = code; 163 | this.zhExplain = zhExplain; 164 | this.enExplain = enExplain; 165 | } 166 | 167 | @Override 168 | public int getCode() { 169 | return code; 170 | } 171 | 172 | @Override 173 | public String toString() { 174 | return code.toString(); 175 | } 176 | 177 | @Override 178 | public String getExplain(LanguageEnum language) { 179 | if (language == LanguageEnum.zh_CN) { 180 | return zhExplain; 181 | } else { 182 | return enExplain; 183 | } 184 | } 185 | } 186 | 187 | /** 188 | * 用户登录权限相关(310~399) 189 | */ 190 | @Description("用户登录权限相关(310~399)") 191 | public enum LoginRegister implements ResponseCode { 192 | /** 193 | * 返回码--用户登录注册--手机号码不能为空 194 | */ 195 | PHONE_EMPTY(310, "手机号码不能为空", "Phone number cannot be empty"), 196 | /** 197 | * 返回码--用户登录注册--密码不能为空 198 | */ 199 | PASSWORD_EMPTY(311, "密码不能为空", "Password cannot be empty"), 200 | /** 201 | * 返回码--用户登录注册--用户不存在 202 | */ 203 | USER_NO_EXISTS(312, "用户不存在", "The user does not exist"), 204 | /** 205 | * 返回码--用户登录注册--用户名已锁定 206 | */ 207 | USER_LOCKED(313, "用户已锁定", "The user has been locked"), 208 | /** 209 | * 返回码--用户登录注册--用户名或密码错误,请重新输入 210 | */ 211 | PWD_INPUT_ERROR(314, "用户名或密码错误,请重新输入", "User name or password error, please re-enter"), 212 | /** 213 | * 返回码--用户登录注册--密码输入错误次数已超过上限 214 | */ 215 | PWD_INPUT_ERROR_LIMIT(315, "密码输入错误超过上限,请${time}分钟后重新输入", "Password error more than limit, please re-enter ${time} minutes"), 216 | /** 217 | * 返回码--用户登录注册--第三方账号未注册(补充注册时使用,不要提示文字) 218 | */ 219 | THIRD_NO_REGISTER(316, "第三方账号未注册", "The third party account registered"), 220 | /** 221 | * 返回码--用户登录注册--手机号码已注册 222 | */ 223 | PHONE_EXISTS(317, "手机号码已注册", "Registered mobile phone number"), 224 | /** 225 | * 返回码--用户登录注册--未登录 226 | */ 227 | NOLOGIN(318, "未登录或登陆超时", "Not login or login timeout"), 228 | /** 229 | * 返回码--用户登录注册--昵称不能为空 230 | */ 231 | NICKNAME_EMPTY(319, "昵称不能为空", "nick cannot be empty"), 232 | /** 233 | * 返回码--用户登录注册--国际码不能为空 234 | */ 235 | SMSCODE_EMPTY(320, "国际码不能为空", "The international code cannot be empty"), 236 | /** 237 | * 返回码--用户登录注册--手机号码不合法 238 | */ 239 | PHONE_NO_VALID(321, "手机号码不合法", "Phone number is no valid"), 240 | 241 | /** 242 | * 返回码--用户登录注册--密码不合法 243 | */ 244 | PASSWORD_NO_VALID(322, "密码不合法", "Password is no valid"), 245 | 246 | /** 247 | * 返回码--用户登录注册--昵称不合法 248 | */ 249 | NICK_NAME_NO_VALID(323, "昵称不合法", "Nick name is no valid"), 250 | /** 251 | * 返回码--用户登录注册--头像不能为空 252 | */ 253 | HEADICON_EMPTY(324, "头像不能为空", "head icon cannot be empty"), 254 | /** 255 | * 返回码--忘记密码--验证码不能为空 256 | */ 257 | VERIFY_CODE(325, "图形验证码不能为空", "verify code cannot be empty"), 258 | /** 259 | * 返回码--忘记密码--验证码错误 260 | */ 261 | VERIFY_CODE_ERROR(326, "图形验证码错误", "verify code error"), 262 | /** 263 | * 返回码--获取desKey--获取失败 264 | */ 265 | GET_KEY_ERROR(327, "获取Key失败", "get key fail"),; 266 | 267 | private final Integer code; 268 | private String zhExplain; 269 | private String enExplain; 270 | 271 | private LoginRegister(int code) { 272 | this.code = code; 273 | } 274 | 275 | private LoginRegister(Integer code, String zhExplain) { 276 | this.code = code; 277 | this.zhExplain = zhExplain; 278 | } 279 | 280 | private LoginRegister(Integer code, String zhExplain, String enExplain) { 281 | this.code = code; 282 | this.zhExplain = zhExplain; 283 | this.enExplain = enExplain; 284 | } 285 | 286 | @Override 287 | public int getCode() { 288 | return code; 289 | } 290 | 291 | @Override 292 | public String toString() { 293 | return code.toString(); 294 | } 295 | 296 | @Override 297 | public String getExplain(LanguageEnum language) { 298 | if (language == LanguageEnum.zh_CN) { 299 | return zhExplain; 300 | } else { 301 | return enExplain; 302 | } 303 | } 304 | } 305 | 306 | 307 | } 308 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/Service.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | import org.apache.ibatis.exceptions.TooManyResultsException; 4 | import tk.mybatis.mapper.entity.Condition; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Service 层 基础接口,其他Service 接口 请继承该接口 10 | */ 11 | public interface Service { 12 | void save(T model);//持久化 13 | void save(List models);//批量持久化 14 | void deleteById(Integer id);//通过主鍵刪除 15 | void deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4” 16 | void update(T model);//更新 17 | T findById(Integer id);//通过ID查找 18 | T findBy(String fieldName, Object value) throws TooManyResultsException; //通过Model中某个成员变量名称(非数据表中column的名称)查找,value需符合unique约束 19 | List findByIds(String ids);//通过多个ID查找//eg:ids -> “1,2,3,4” 20 | List findByCondition(Condition condition);//根据条件查找 21 | List findAll();//获取所有 22 | } 23 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/ServiceApiResponse.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | import java.io.Serializable; 4 | import java.util.Map; 5 | 6 | /** 7 | * API结果返回对象 8 | * 9 | *

10 | * 注意:此类用于Service(dubbo)层返回{@link ApiResponse}数据信息,在Controll层调用Service层得到此对象后,需要包装后才能得到ApiResponse 11 | *

12 | * 13 | *

14 | * 使用举例:
15 | *
16 | * 17 | * {@code ApiResponse apiResponse = ApiResponse.getApiResponse(serviceApiResponse);} 18 | * 19 | *

20 | * 21 | * @author droxy 22 | * @date 2017年3月24日 上午10:30:03 23 | * 24 | */ 25 | public class ServiceApiResponse implements Serializable { 26 | 27 | private static final long serialVersionUID = 1L; 28 | 29 | private ResponseCode code = ResponseCode.Base.ERROR; 30 | private Map params; 31 | private Object data; 32 | 33 | public ServiceApiResponse() { 34 | 35 | } 36 | 37 | public ServiceApiResponse(ResponseCode code) { 38 | this.code = code; 39 | } 40 | 41 | public ServiceApiResponse(ResponseCode code, Object data) { 42 | this.code = code; 43 | this.data = data; 44 | } 45 | 46 | public ServiceApiResponse(ResponseCode code, Map params, Object data) { 47 | this.code = code; 48 | this.params = params; 49 | this.data = data; 50 | } 51 | 52 | public static ServiceApiResponse creatSuccess() { 53 | return creatSuccess(null); 54 | } 55 | 56 | public static ServiceApiResponse creatSuccess(Object data) { 57 | return creatSuccess(ResponseCode.Base.SUCCESS, data); 58 | } 59 | 60 | public static ServiceApiResponse creatSuccess(ResponseCode responseCode, Object data) { 61 | return creatSuccess(responseCode, null, data); 62 | } 63 | 64 | public static ServiceApiResponse creatSuccess(ResponseCode responseCode, Map params, Object data) { 65 | return new ServiceApiResponse(responseCode, params, data); 66 | } 67 | 68 | public static ServiceApiResponse creatFail(ResponseCode responseCode) { 69 | return creatFail(responseCode, null); 70 | } 71 | 72 | public static ServiceApiResponse creatFail(ResponseCode responseCode, Object data) { 73 | return creatFail(responseCode, null, data); 74 | } 75 | 76 | public static ServiceApiResponse creatFail(ResponseCode responseCode, Map params) { 77 | return creatFail(responseCode, params, null); 78 | } 79 | 80 | public static ServiceApiResponse creatFail(ResponseCode responseCode, Map params, Object data) { 81 | return new ServiceApiResponse(responseCode, params, data); 82 | } 83 | 84 | public ResponseCode getCode() { 85 | return code; 86 | } 87 | 88 | public void setCode(ResponseCode code) { 89 | this.code = code; 90 | } 91 | 92 | public Object getData() { 93 | return data; 94 | } 95 | 96 | public void setData(Object data) { 97 | this.data = data; 98 | } 99 | 100 | public Map getParams() { 101 | return params; 102 | } 103 | 104 | public void setParams(Map params) { 105 | this.params = params; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/core/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.core; 2 | 3 | /** 4 | * 服务(业务)异常如“ 账号或密码错误 ”,该异常只做INFO级别的日志记录 @see WebMvcConfigurer 5 | */ 6 | public class ServiceException extends RuntimeException { 7 | public ServiceException() { 8 | } 9 | 10 | public ServiceException(String message) { 11 | super(message); 12 | } 13 | 14 | public ServiceException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/intercept/LoginInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.intercept; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.SerializerFeature; 5 | import com.rogge.common.conf.redis.SessionUserInfo; 6 | import com.rogge.common.core.ApiResponse; 7 | import com.rogge.common.core.ResponseCode; 8 | import com.rogge.common.model.User; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.servlet.HandlerInterceptor; 11 | import org.springframework.web.servlet.ModelAndView; 12 | 13 | import javax.annotation.Resource; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | 17 | @Component 18 | public class LoginInterceptor implements HandlerInterceptor { 19 | 20 | @Resource 21 | private SessionUserInfo sessionUserInfo; 22 | 23 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 24 | // 未登录 25 | User user = sessionUserInfo.getCurrentSessionUser(User.class); 26 | if (user == null) { 27 | ApiResponse apiResponse = ApiResponse.creatFail(ResponseCode.LoginRegister.NOLOGIN); 28 | response.setContentType("application/json;charset=UTF-8"); 29 | response.getWriter().print(JSON.toJSONString(apiResponse, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteEnumUsingToString)); 30 | return false; 31 | } else { 32 | sessionUserInfo.setSessionUser(user); 33 | } 34 | return true; 35 | } 36 | 37 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 38 | 39 | } 40 | 41 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/model/KeyValue.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public class KeyValue implements Serializable { 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = 1L; 11 | 12 | 13 | private Object key; 14 | private Object value; 15 | 16 | public KeyValue() { 17 | 18 | } 19 | 20 | public KeyValue(Object key, Object value) { 21 | this.key = key; 22 | this.value = value; 23 | } 24 | 25 | public Object getKey() { 26 | return key; 27 | } 28 | 29 | public void setKey(Object key) { 30 | this.key = key; 31 | } 32 | 33 | public Object getValue() { 34 | return value; 35 | } 36 | 37 | public void setValue(Object value) { 38 | this.value = value; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "KeyValue [key=" + key + ", value=" + value + "]"; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/model/LanguageEnum.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.model; 2 | 3 | /** 4 | * 语言类型 5 | * 6 | * @author droxy 7 | * @date 2017年3月23日 下午5:05:19 8 | * 9 | */ 10 | public enum LanguageEnum { 11 | 12 | /** 中文 **/ 13 | zh_CN, 14 | /** 英文 **/ 15 | en; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/model/SessionUser.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 会话用户(一般指登录用户) 7 | * 8 | * @author droxy 9 | * 10 | */ 11 | public abstract class SessionUser implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | /** 用户主键id **/ 16 | public abstract Integer getId(); 17 | 18 | /** 用户名 **/ 19 | public abstract String getUsername(); 20 | 21 | /** 用户类型名称 **/ 22 | public String getUserType() { 23 | return getClass().getSimpleName(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/model/User.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.model; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import java.util.Date; 8 | 9 | public class User extends SessionUser{ 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer id; 13 | 14 | private String username; 15 | 16 | private String password; 17 | 18 | @Column(name = "nick_name") 19 | private String nickName; 20 | 21 | private Integer sex; 22 | 23 | @Column(name = "register_date") 24 | private Date registerDate; 25 | 26 | private String email; 27 | 28 | @Column(name = "pass_word") 29 | private String passWord; 30 | 31 | @Column(name = "reg_time") 32 | private String regTime; 33 | 34 | @Column(name = "user_name") 35 | private String userName; 36 | 37 | /** 38 | * @return id 39 | */ 40 | public Integer getId() { 41 | return id; 42 | } 43 | 44 | /** 45 | * @param id 46 | */ 47 | public void setId(Integer id) { 48 | this.id = id; 49 | } 50 | 51 | /** 52 | * @return username 53 | */ 54 | public String getUsername() { 55 | return username; 56 | } 57 | 58 | /** 59 | * @param username 60 | */ 61 | public void setUsername(String username) { 62 | this.username = username; 63 | } 64 | 65 | /** 66 | * @return password 67 | */ 68 | public String getPassword() { 69 | return password; 70 | } 71 | 72 | /** 73 | * @param password 74 | */ 75 | public void setPassword(String password) { 76 | this.password = password; 77 | } 78 | 79 | /** 80 | * @return nick_name 81 | */ 82 | public String getNickName() { 83 | return nickName; 84 | } 85 | 86 | /** 87 | * @param nickName 88 | */ 89 | public void setNickName(String nickName) { 90 | this.nickName = nickName; 91 | } 92 | 93 | /** 94 | * @return sex 95 | */ 96 | public Integer getSex() { 97 | return sex; 98 | } 99 | 100 | /** 101 | * @param sex 102 | */ 103 | public void setSex(Integer sex) { 104 | this.sex = sex; 105 | } 106 | 107 | /** 108 | * @return register_date 109 | */ 110 | public Date getRegisterDate() { 111 | return registerDate; 112 | } 113 | 114 | /** 115 | * @param registerDate 116 | */ 117 | public void setRegisterDate(Date registerDate) { 118 | this.registerDate = registerDate; 119 | } 120 | 121 | /** 122 | * @return email 123 | */ 124 | public String getEmail() { 125 | return email; 126 | } 127 | 128 | /** 129 | * @param email 130 | */ 131 | public void setEmail(String email) { 132 | this.email = email; 133 | } 134 | 135 | /** 136 | * @return pass_word 137 | */ 138 | public String getPassWord() { 139 | return passWord; 140 | } 141 | 142 | /** 143 | * @param passWord 144 | */ 145 | public void setPassWord(String passWord) { 146 | this.passWord = passWord; 147 | } 148 | 149 | /** 150 | * @return reg_time 151 | */ 152 | public String getRegTime() { 153 | return regTime; 154 | } 155 | 156 | /** 157 | * @param regTime 158 | */ 159 | public void setRegTime(String regTime) { 160 | this.regTime = regTime; 161 | } 162 | 163 | /** 164 | * @return user_name 165 | */ 166 | public String getUserName() { 167 | return userName; 168 | } 169 | 170 | /** 171 | * @param userName 172 | */ 173 | public void setUserName(String userName) { 174 | this.userName = userName; 175 | } 176 | } -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/model/Visitor.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | public class Visitor implements Serializable { 7 | 8 | private static final long serialVersionUID = 1L; 9 | 10 | private SessionUser sessionUser; 11 | private String sessionId; 12 | private String ip; 13 | private String browser; 14 | private Date loginDate; 15 | 16 | // 在线时间 17 | private String onlineTimeStr; 18 | 19 | public String getOnlineTimeStr() { 20 | String str = ""; 21 | Date date = new Date(); 22 | long gap = date.getTime() - loginDate.getTime(); 23 | if (gap < 10 * 1000) { 24 | onlineTimeStr = "刚刚"; 25 | } else { 26 | if (gap < 60 * 1000) { 27 | str = gap / 1000 + "秒"; 28 | } else if (gap < 60 * 60 * 1000) { 29 | str = gap / (60 * 1000) + "分钟"; 30 | } else if (gap < 24 * 60 * 60 * 1000) { 31 | str = gap / (60 * 60 * 1000) + "小时"; 32 | } else { 33 | str = gap / (24 * 60 * 60 * 1000) + "天"; 34 | } 35 | onlineTimeStr = str + "之前"; 36 | } 37 | return onlineTimeStr; 38 | } 39 | 40 | public Date getLoginDate() { 41 | return loginDate; 42 | } 43 | 44 | public void setLoginDate(Date loginDate) { 45 | this.loginDate = loginDate; 46 | } 47 | 48 | public SessionUser getSessionUser() { 49 | return sessionUser; 50 | } 51 | 52 | public void setSessionUser(SessionUser sessionUser) { 53 | this.sessionUser = sessionUser; 54 | } 55 | 56 | public String getSessionId() { 57 | return sessionId; 58 | } 59 | 60 | public void setSessionId(String sessionId) { 61 | this.sessionId = sessionId; 62 | } 63 | 64 | public void setOnlineTimeStr(String onlineTimeStr) { 65 | this.onlineTimeStr = onlineTimeStr; 66 | } 67 | 68 | public String getIp() { 69 | return ip; 70 | } 71 | 72 | public void setIp(String ip) { 73 | this.ip = ip; 74 | } 75 | 76 | public String getBrowser() { 77 | return browser; 78 | } 79 | 80 | public void setBrowser(String browser) { 81 | this.browser = browser; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/util/UUIDGenerator.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.util; 2 | 3 | import java.util.UUID; 4 | 5 | /** 6 | * [Description] 7 | *

8 | * [How to use] 9 | *

10 | * [Tips] 11 | * 12 | * @author Created by Rogge on 2018/03/21 13 | * @since 1.0.0 14 | */ 15 | public class UUIDGenerator { 16 | private UUIDGenerator() { 17 | } 18 | 19 | public static String getUUID() { 20 | String str = UUID.randomUUID().toString(); 21 | str = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24); 22 | return str.substring(0, 20); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /common-module/src/main/java/com/rogge/common/util/Util.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common.util; 2 | 3 | import com.rogge.common.Constant; 4 | import com.rogge.common.model.KeyValue; 5 | import com.rogge.common.model.LanguageEnum; 6 | import org.apache.commons.logging.Log; 7 | import org.apache.commons.logging.LogFactory; 8 | import org.springframework.web.context.request.RequestContextHolder; 9 | import org.springframework.web.context.request.ServletRequestAttributes; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpSession; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import java.util.regex.Matcher; 16 | import java.util.regex.Pattern; 17 | 18 | public class Util { 19 | 20 | public static Log logger = LogFactory.getLog(Util.class); 21 | 22 | /** 23 | * 获取真实IP 24 | * 25 | * @param request 26 | * @return 27 | */ 28 | public static String getIpAddr(HttpServletRequest request) { 29 | String ip = request.getHeader("x-forwarded-for"); 30 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 31 | ip = request.getHeader("Proxy-Client-IP"); 32 | } 33 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 34 | ip = request.getHeader("WL-Proxy-Client-IP"); 35 | } 36 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 37 | ip = request.getRemoteAddr(); 38 | } 39 | return ip; 40 | } 41 | 42 | /** 43 | * 快速组装Map 44 | * 45 | * @param kvs 46 | * @return 47 | */ 48 | public static Map getSimpleMap(KeyValue... kvs) { 49 | Map map = new HashMap<>(); 50 | if (kvs != null) { 51 | for (KeyValue kv : kvs) { 52 | map.put(kv.getKey() + "", kv.getValue()); 53 | } 54 | } 55 | return map; 56 | } 57 | 58 | /** 59 | * 设置当前会话语言 60 | * 61 | * @param language 62 | * @return 失败返回false 63 | */ 64 | public static boolean setCurrentLanguage(HttpSession session, LanguageEnum language) { 65 | try { 66 | session.setAttribute(Constant.CURRENT_LANGUAGE, language); 67 | return true; 68 | } catch (Exception e) { 69 | } 70 | return false; 71 | } 72 | 73 | /** 74 | * 获取当前会话语言(如果找不到默认返回中文) 75 | * 76 | * @return 77 | */ 78 | public static LanguageEnum getCurrentLanguage() { 79 | try { 80 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 81 | LanguageEnum language = (LanguageEnum) request.getSession().getAttribute(Constant.CURRENT_LANGUAGE); 82 | if (language != null) { 83 | return language; 84 | } 85 | } catch (Exception e) { 86 | } 87 | return LanguageEnum.zh_CN; 88 | } 89 | 90 | /** 91 | * 填充消息占位符 92 | * 93 | * @param msg 94 | * @return 95 | */ 96 | public static String convertParam(String msg, Map params) { 97 | Pattern pattern = Pattern.compile("\\$\\{\\w*\\}"); 98 | Matcher matcher = pattern.matcher(msg); 99 | matcher.reset(); 100 | StringBuffer sb = new StringBuffer(); 101 | while (matcher.find()) { 102 | String str = matcher.group(); 103 | String key = str.substring(2, str.length() - 1); 104 | if (params == null) { 105 | logger.warn("参数为空"); 106 | return msg; 107 | } 108 | Object value = params.get(key); 109 | if (value == null) { 110 | logger.warn("找不到参数[" + key + "]对应的值,请检查参数列表:" + params); 111 | } 112 | matcher.appendReplacement(sb, value == null ? "" : value.toString()); 113 | } 114 | matcher.appendTail(sb); 115 | return sb.toString(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /common-module/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | hosts: 2 | user: 127.0.0.1:8081/rogge 3 | command: 127.0.0.1:8082/rogge 4 | order: 127.0.0.1:8083/rogge -------------------------------------------------------------------------------- /common-module/src/test/java/com/rogge/common/CommonModuleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.rogge.common; 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 CommonModuleApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /config/gateway-service-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 80 3 | 4 | hosts: 5 | user-eureka: http://localhost:8089 6 | 7 | spring: 8 | output: 9 | ansi: 10 | enabled: always #多彩log 11 | 12 | management: 13 | security: 14 | enabled: false 15 | 16 | logging: 17 | level: 18 | com.rogge: debug 19 | file: ./logs/gateway.log 20 | root: info 21 | 22 | eureka: 23 | client: 24 | serviceUrl: 25 | defaultZone: ${hosts.user-eureka}/eureka/ 26 | instance: 27 | preferIpAddress: true 28 | instance-id: ${spring.application.name}:${server.port} 29 | 30 | zuul: 31 | routes: 32 | user: 33 | path: /user/** 34 | serviceId: user-module 35 | sensitiveHeaders: Cookie,Set-Cookie,Authorization 36 | order: 37 | path: /order/** 38 | serviceId: order-module 39 | sensitiveHeaders: Cookie,Set-Cookie,Authorization 40 | # command: 41 | # path: /command/** 42 | # serviceId: command-module 43 | 44 | -------------------------------------------------------------------------------- /config/order-module-dev.yml: -------------------------------------------------------------------------------- 1 | person: 2 | name: wulei 3 | 4 | hosts: 5 | user-eureka: http://localhost:8089 6 | 7 | server: 8 | port: 8083 9 | 10 | spring: 11 | application: 12 | name: order-module 13 | output: 14 | ansi: 15 | enabled: always #多彩log 16 | 17 | hystrix: 18 | command: 19 | default: 20 | execution: 21 | isolation: 22 | strategy: SEMAPHORE 23 | 24 | management: 25 | security: 26 | enabled: false 27 | 28 | logging: 29 | level: 30 | com.rogge: debug 31 | file: ./logs/order.log 32 | root: info 33 | 34 | eureka: 35 | client: 36 | serviceUrl: 37 | defaultZone: ${hosts.user-eureka}/eureka/ 38 | instance: 39 | preferIpAddress: true 40 | instance-id: ${spring.application.name}:${server.port} 41 | -------------------------------------------------------------------------------- /discovery-module/.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/ -------------------------------------------------------------------------------- /discovery-module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.rogge.discovery 7 | discovery-module 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | discovery-module 12 | Demo project for Spring Boot 13 | 14 | 15 | com.rogge 16 | scloud 17 | 0.0.1-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-eureka-server 30 | 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-config-server 35 | 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-starter-zuul 40 | 41 | 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-maven-plugin 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /discovery-module/src/main/java/com/rogge/discovery/DiscoveryModuleApplication.java: -------------------------------------------------------------------------------- 1 | package com.rogge.discovery; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.config.server.EnableConfigServer; 6 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 7 | 8 | @EnableEurekaServer 9 | @EnableConfigServer 10 | @SpringBootApplication 11 | public class DiscoveryModuleApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(DiscoveryModuleApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /discovery-module/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8089 3 | 4 | eureka: 5 | client: 6 | register-with-eureka: false 7 | fetch-registry: false 8 | serviceUrl: 9 | defaultZone: http://localhost:${server.port}/eureka/ 10 | 11 | spring: 12 | application: 13 | name: all-server 14 | output: 15 | ansi: 16 | enabled: always #多彩log 17 | # profiles: 18 | # active: native 19 | cloud: 20 | config: 21 | server: 22 | git: 23 | uri: https://github.com/Rogge666/spring-cloud.git 24 | searchPaths: config 25 | username: 26 | password: 27 | # native: 28 | # search-locations: file:C:\\Users\\Administrator\\Desktop\\config 29 | # search-locations: classpath:/properties/ 30 | label: master 31 | -------------------------------------------------------------------------------- /discovery-module/src/main/resources/properties/gateway-service-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 80 3 | 4 | hosts: 5 | user-eureka: http://localhost:8089 6 | 7 | spring: 8 | output: 9 | ansi: 10 | enabled: always #多彩log 11 | 12 | management: 13 | security: 14 | enabled: false 15 | 16 | logging: 17 | level: 18 | com.rogge: debug 19 | file: ./logs/gateway.log 20 | root: info 21 | 22 | eureka: 23 | client: 24 | serviceUrl: 25 | defaultZone: ${hosts.user-eureka}/eureka/ 26 | instance: 27 | preferIpAddress: true 28 | instance-id: ${spring.application.name}:${server.port} 29 | 30 | zuul: 31 | routes: 32 | user: 33 | path: /user-api/** 34 | serviceId: user-module 35 | order: 36 | path: /order-api/** 37 | serviceId: order-module 38 | # command: 39 | # path: /command-api/** 40 | # serviceId: command-module 41 | 42 | -------------------------------------------------------------------------------- /discovery-module/src/main/resources/properties/order-module-dev.yml: -------------------------------------------------------------------------------- 1 | person: 2 | name: wulei 3 | 4 | hosts: 5 | user-eureka: http://localhost:8089 6 | 7 | server: 8 | port: 8083 9 | 10 | spring: 11 | datasource: 12 | type: com.alibaba.druid.pool.DruidDataSource 13 | driver-class-name: com.mysql.jdbc.Driver 14 | url: jdbc:mysql://127.0.0.1:3306/rogge?autoReconnect=true&useUnicode=true&characterEncoding=utf8 15 | username: root 16 | password: 123456 17 | application: 18 | name: order-module 19 | # rabbitmq: 20 | # host: localhost 21 | # port: 8161 22 | # username: admin 23 | # password: admin 24 | output: 25 | ansi: 26 | enabled: always #多彩log 27 | 28 | management: 29 | security: 30 | enabled: false 31 | 32 | logging: 33 | level: 34 | com.rogge: debug 35 | file: ./logs/order.log 36 | root: info 37 | 38 | eureka: 39 | client: 40 | serviceUrl: 41 | defaultZone: ${hosts.user-eureka}/eureka/ 42 | instance: 43 | preferIpAddress: true 44 | instance-id: ${spring.application.name}:${server.port} 45 | -------------------------------------------------------------------------------- /discovery-module/src/test/java/com/rogge/discovery/DiscoveryModuleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.rogge.discovery; 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 DiscoveryModuleApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /gateway-service/.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/ -------------------------------------------------------------------------------- /gateway-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.rogge.gateway 7 | gateway-service 8 | 0.0.1-SNAPSHOT 9 | war 10 | 11 | gateway-service 12 | Demo project for Spring Boot 13 | 14 | 15 | com.rogge 16 | scloud 17 | 0.0.1-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | com.rogge.common 29 | common-module 30 | 0.0.1-SNAPSHOT 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-zuul 35 | 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-starter-config 40 | 41 | 42 | 43 | org.springframework.session 44 | spring-session-data-redis 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-maven-plugin 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /gateway-service/src/main/java/com/rogge/gateway/GatewayServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.rogge.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.cloud.context.config.annotation.RefreshScope; 7 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 8 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 9 | import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.ComponentScan; 12 | import org.springframework.session.data.redis.RedisFlushMode; 13 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 14 | 15 | @SpringBootApplication 16 | @EnableZuulProxy 17 | @EnableEurekaClient 18 | @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) 19 | @ComponentScan(basePackages={"com.rogge.common","com.rogge.gateway"}) 20 | public class GatewayServiceApplication { 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(GatewayServiceApplication.class, args); 24 | } 25 | 26 | @Bean 27 | @RefreshScope 28 | @ConfigurationProperties("zuul") 29 | public ZuulProperties zuulProperties() { 30 | return new ZuulProperties(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gateway-service/src/main/java/com/rogge/gateway/SessionFilter.java: -------------------------------------------------------------------------------- 1 | package com.rogge.gateway; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.SerializerFeature; 5 | import com.netflix.zuul.ZuulFilter; 6 | import com.netflix.zuul.context.RequestContext; 7 | import com.rogge.common.conf.redis.SessionUserInfo; 8 | import com.rogge.common.core.ApiResponse; 9 | import com.rogge.common.core.ResponseCode; 10 | import com.rogge.common.model.User; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.session.Session; 13 | import org.springframework.session.SessionRepository; 14 | import org.springframework.stereotype.Component; 15 | 16 | import javax.annotation.Resource; 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpServletResponse; 19 | import javax.servlet.http.HttpSession; 20 | import java.io.IOException; 21 | 22 | /** 23 | * [Description] 24 | *

25 | * [How to use] 26 | *

27 | * [Tips] 28 | * 29 | * @author Created by Rogge on 2017/11/7. 30 | * @since 1.0.0 31 | */ 32 | @Component 33 | public class SessionFilter extends ZuulFilter { 34 | 35 | @Autowired 36 | private SessionRepository repository; 37 | 38 | @Resource 39 | public SessionUserInfo mSessionUserInfo; 40 | 41 | private static final String[] ignoreUrl = {"/user/login","/user/list"}; 42 | 43 | @Override 44 | public String filterType() { 45 | return "pre"; 46 | } 47 | 48 | @Override 49 | public int filterOrder() { 50 | return 1; 51 | } 52 | 53 | @Override 54 | public boolean shouldFilter() { 55 | return true; 56 | } 57 | 58 | @Override 59 | public Object run() { 60 | RequestContext ctx = RequestContext.getCurrentContext(); 61 | HttpSession httpSession = ctx.getRequest().getSession(); 62 | Session session = repository.getSession(httpSession.getId()); 63 | ctx.addZuulRequestHeader("Cookie", "SESSION=" + session.getId()); 64 | 65 | HttpServletRequest request = ctx.getRequest(); 66 | HttpServletResponse response = ctx.getResponse(); 67 | String requestUri = request.getRequestURI(); 68 | //当前请求为不需要检查权限的url配置时 69 | if(isStartWith(requestUri)){ 70 | return null; 71 | } 72 | User user = mSessionUserInfo.getCurrentSessionUser(User.class); 73 | if (user == null){ 74 | ctx.setSendZuulResponse(false);// 过滤该请求,不对其进行路由 75 | ApiResponse apiResponse = ApiResponse.creatFail(ResponseCode.LoginRegister.NOLOGIN); 76 | response.setContentType("application/json;charset=UTF-8"); 77 | try { 78 | response.getWriter().print(JSON.toJSONString(apiResponse, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteEnumUsingToString)); 79 | } catch (IOException e) { 80 | e.printStackTrace(); 81 | } 82 | }else { 83 | mSessionUserInfo.setSessionUser(user); 84 | } 85 | return null; 86 | } 87 | 88 | /** 89 | * 是否配置的不用检查的url权限 90 | * @param requestUri 91 | * @return 92 | */ 93 | private boolean isStartWith(String requestUri) { 94 | boolean flag = false; 95 | for (String s : ignoreUrl) { 96 | if (requestUri.startsWith(s)) { 97 | return true; 98 | } 99 | } 100 | return flag; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /gateway-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: gateway-service 4 | output: 5 | ansi: 6 | enabled: always #多彩log 7 | cloud: 8 | config: 9 | uri: http://localhost:8089/ 10 | name: gateway-service 11 | profile: dev 12 | label: master -------------------------------------------------------------------------------- /gateway-service/src/test/java/com/rogge/gateway/GatewayServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.rogge.gateway; 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 GatewayServiceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /order-module/.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/ -------------------------------------------------------------------------------- /order-module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.rogge.order 7 | order-module 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | order-module 12 | Demo project for Spring Boot 13 | 14 | 15 | com.rogge 16 | scloud 17 | 0.0.1-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | com.rogge.common 29 | common-module 30 | 0.0.1-SNAPSHOT 31 | 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-ribbon 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-config 42 | 43 | 44 | 45 | 46 | org.springframework.cloud 47 | spring-cloud-starter-hystrix 48 | 49 | 50 | 51 | org.springframework.cloud 52 | spring-cloud-starter-feign 53 | 54 | 55 | 56 | 57 | com.dangdang 58 | sharding-jdbc-core 59 | 1.5.4.1 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-maven-plugin 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/OrderModuleApplication.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 6 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 7 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 8 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.ComponentScan; 11 | import org.springframework.session.data.redis.RedisFlushMode; 12 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 13 | import org.springframework.web.client.RestTemplate; 14 | 15 | @SpringBootApplication 16 | @EnableEurekaClient 17 | @EnableCircuitBreaker 18 | @EnableFeignClients 19 | @ComponentScan(basePackages={"com.rogge.common","com.rogge.order"}) 20 | @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) 21 | public class OrderModuleApplication { 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(OrderModuleApplication.class, args); 25 | } 26 | 27 | @Bean 28 | @LoadBalanced 29 | public RestTemplate RestTemplate(){ 30 | return new RestTemplate(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/algorithm/OrderDatabaseAlgorithm.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.algorithm; 2 | 3 | import com.dangdang.ddframe.rdb.sharding.api.ShardingValue; 4 | import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm; 5 | import com.google.common.collect.Range; 6 | 7 | import java.util.Collection; 8 | import java.util.LinkedHashSet; 9 | 10 | /** 11 | * [Description] 12 | *

13 | * [How to use] 14 | *

15 | * [Tips] 16 | * 17 | * @author Created by Rogge on 2018/4/7 18 | * @since 1.0.0 19 | */ 20 | public class OrderDatabaseAlgorithm implements SingleKeyDatabaseShardingAlgorithm { 21 | @Override 22 | public String doEqualSharding(Collection collection, ShardingValue shardingValue) { 23 | for (String each : collection) { 24 | if (each.endsWith(shardingValue.getValue() % 2 + "")) { 25 | return each; 26 | } 27 | } 28 | throw new IllegalArgumentException(); 29 | } 30 | 31 | @Override 32 | public Collection doInSharding(Collection collection, ShardingValue shardingValue) { 33 | Collection result = new LinkedHashSet<>(collection.size()); 34 | for (Long value : shardingValue.getValues()) { 35 | for (String tableName : collection) { 36 | if (tableName.endsWith(value % 2 + "")) { 37 | result.add(tableName); 38 | } 39 | } 40 | } 41 | return result; 42 | } 43 | 44 | @Override 45 | public Collection doBetweenSharding(Collection collection, ShardingValue shardingValue) { 46 | Collection result = new LinkedHashSet<>(collection.size()); 47 | Range range = shardingValue.getValueRange(); 48 | for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) { 49 | for (String each : collection) { 50 | if (each.endsWith(i % 2 + "")) { 51 | result.add(each); 52 | } 53 | } 54 | } 55 | return result; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/algorithm/OrderTableAlgorithm.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.algorithm; 2 | 3 | import com.dangdang.ddframe.rdb.sharding.api.ShardingValue; 4 | import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm; 5 | import com.google.common.collect.Range; 6 | 7 | import java.util.Collection; 8 | import java.util.LinkedHashSet; 9 | 10 | /** 11 | * [Description] 12 | *

13 | * [How to use] 14 | *

15 | * [Tips] 16 | * 17 | * @author Created by Rogge on 2018/4/7 18 | * @since 1.0.0 19 | */ 20 | public class OrderTableAlgorithm implements SingleKeyTableShardingAlgorithm { 21 | 22 | @Override 23 | public String doEqualSharding(final Collection collection, final ShardingValue shardingValue) { 24 | for (String each : collection) { 25 | if (each.endsWith(shardingValue.getValue() % 2 + "")) { 26 | return each; 27 | } 28 | } 29 | throw new IllegalArgumentException(); 30 | } 31 | 32 | @Override 33 | public Collection doInSharding(final Collection collection, final ShardingValue shardingValue) { 34 | Collection result = new LinkedHashSet<>(collection.size()); 35 | for (Long value : shardingValue.getValues()) { 36 | for (String tableName : collection) { 37 | if (tableName.endsWith(value % 2 + "")) { 38 | result.add(tableName); 39 | } 40 | } 41 | } 42 | return result; 43 | } 44 | 45 | @Override 46 | public Collection doBetweenSharding(final Collection collection, final ShardingValue shardingValue) { 47 | Collection result = new LinkedHashSet<>(collection.size()); 48 | Range range = shardingValue.getValueRange(); 49 | for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) { 50 | for (String each : collection) { 51 | if (each.endsWith(i % 2 + "")) { 52 | result.add(each); 53 | } 54 | } 55 | } 56 | return result; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/conf/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.conf; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSourceFactory; 5 | import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule; 6 | import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule; 7 | import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule; 8 | import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy; 9 | import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy; 10 | import com.rogge.order.algorithm.OrderDatabaseAlgorithm; 11 | import com.rogge.order.algorithm.OrderTableAlgorithm; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | 15 | import javax.sql.DataSource; 16 | import java.sql.SQLException; 17 | import java.util.Arrays; 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | 22 | /** 23 | * [Description] 24 | *

25 | * [How to use] 26 | *

27 | * [Tips] 28 | * 29 | * @author Created by Rogge on 2018/4/7 30 | * @since 1.0.0 31 | */ 32 | @Configuration 33 | public class DataSourceConfig { 34 | @Bean 35 | public DataSource getDataSource() throws SQLException { 36 | return buildDataSource(); 37 | } 38 | 39 | private DataSource buildDataSource() throws SQLException { 40 | //设置分库映射 41 | Map dataSourceMap = new HashMap<>(2); 42 | //添加两个数据库order_0,order_1到map里 43 | dataSourceMap.put("order_0", createDataSource("order_0")); 44 | dataSourceMap.put("order_1", createDataSource("order_1")); 45 | 46 | //设置默认db为order_0,也就是为那些没有配置分库分表策略的指定的默认库 47 | //如果只有一个库,也就是不需要分库的话,map里只放一个映射就行了, 48 | // 只有一个库时不需要指定默认库, 49 | // 但2个及以上时必须指定默认库,否则那些没有配置策略的表将无法操作数据 50 | DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap,"order_0"); 51 | 52 | 53 | //设置分表映射,将t_order_0和t_order_1两个实际的表映射到t_order逻辑表 54 | //0和1两个表是真实的表,t_order是个虚拟不存在的表, 55 | // 只是供使用。如查询所有数据就是select * from t_order就能查完0和1表的 56 | TableRule orderTableRule = TableRule.builder("t_order") 57 | .actualTables(Arrays.asList("t_order_0","t_order_1")) 58 | .dataSourceRule(dataSourceRule) 59 | .build(); 60 | 61 | //具体分库分表策略,按什么规则来分 62 | ShardingRule shardingRule = ShardingRule.builder() 63 | .dataSourceRule(dataSourceRule) 64 | .tableRules(Arrays.asList(orderTableRule)) 65 | .databaseShardingStrategy(new DatabaseShardingStrategy("user_id",new OrderDatabaseAlgorithm())) 66 | .tableShardingStrategy(new TableShardingStrategy("order_id",new OrderTableAlgorithm())).build(); 67 | return ShardingDataSourceFactory.createDataSource(shardingRule); 68 | } 69 | 70 | 71 | /** 72 | * 创建druid数据源 73 | * @param dataSourceName 74 | * @return 75 | */ 76 | private static DataSource createDataSource(final String dataSourceName) { 77 | // 使用Druid连接池连接数据库 78 | DruidDataSource druidDataSource = new DruidDataSource(); 79 | druidDataSource.setDriverClassName("com.mysql.jdbc.Driver"); 80 | druidDataSource.setUrl(String.format("jdbc:mysql://localhost:3306/%s", dataSourceName)); 81 | druidDataSource.setUsername("root"); 82 | druidDataSource.setPassword("123456"); 83 | return druidDataSource; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/conf/FeignConfig.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.conf; 2 | 3 | import com.google.common.base.Strings; 4 | import feign.RequestInterceptor; 5 | import feign.RequestTemplate; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.context.request.RequestContextHolder; 9 | 10 | /** 11 | * [Description] 12 | *

13 | * [How to use] 14 | *

15 | * [Tips] 16 | * 17 | * @author Created by Rogge on 2017/11/7. 18 | * @since 1.0.0 19 | */ 20 | @Configuration 21 | public class FeignConfig { 22 | @Bean 23 | public RequestInterceptor requestInterceptor() { 24 | return new RequestInterceptor() { 25 | @Override 26 | public void apply(RequestTemplate requestTemplate) { 27 | String sessionId = RequestContextHolder.currentRequestAttributes().getSessionId(); 28 | if (!Strings.isNullOrEmpty(sessionId)) { 29 | requestTemplate.header("Cookie", "SESSION=" + sessionId); 30 | } 31 | } 32 | }; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/conf/MybatisConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.conf; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import org.apache.ibatis.plugin.Interceptor; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | import org.mybatis.spring.SqlSessionFactoryBean; 7 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 11 | import org.springframework.core.io.support.ResourcePatternResolver; 12 | import tk.mybatis.spring.mapper.MapperScannerConfigurer; 13 | 14 | import javax.annotation.Resource; 15 | import javax.sql.DataSource; 16 | import java.util.Properties; 17 | 18 | /** 19 | * [Description] 20 | *

21 | * [How to use] 22 | *

23 | * [Tips] 24 | * 25 | * @author Created by Rogge on 2017/10/6 0006. 26 | * @since 1.0.0 27 | */ 28 | @Configuration 29 | public class MybatisConfigurer { 30 | @Resource 31 | private DataSource dataSource; 32 | 33 | @Bean 34 | public SqlSessionFactory sqlSessionFactoryBean() throws Exception { 35 | SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); 36 | bean.setDataSource(dataSource); 37 | bean.setTypeAliasesPackage(ProjectConstant.MODEL_PACKAGE); 38 | 39 | //分页插件 40 | PageHelper pageHelper = new PageHelper(); 41 | Properties properties = new Properties(); 42 | properties.setProperty("reasonable", "true"); 43 | properties.setProperty("supportMethodsArguments", "true"); 44 | properties.setProperty("returnPageInfo", "check"); 45 | properties.setProperty("params", "count=countSql"); 46 | properties.setProperty("pageSizeZero", "true");//分页尺寸为0时查询所有纪录不再执行分页 47 | pageHelper.setProperties(properties); 48 | 49 | //添加插件 50 | bean.setPlugins(new Interceptor[]{pageHelper}); 51 | 52 | //添加XML目录 53 | ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 54 | bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); 55 | return bean.getObject(); 56 | } 57 | 58 | @Configuration 59 | @AutoConfigureAfter(MybatisConfigurer.class) 60 | public static class MyBatisMapperScannerConfigurer { 61 | 62 | @Bean 63 | public MapperScannerConfigurer mapperScannerConfigurer() { 64 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 65 | mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean"); 66 | mapperScannerConfigurer.setBasePackage(ProjectConstant.MAPPER_PACKAGE); 67 | //配置通用mappers 68 | Properties properties = new Properties(); 69 | properties.setProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE); 70 | properties.setProperty("notEmpty", "false"); 71 | properties.setProperty("IDENTITY", "MYSQL"); 72 | mapperScannerConfigurer.setProperties(properties); 73 | return mapperScannerConfigurer; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/conf/ProjectConstant.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.conf; 2 | 3 | /** 4 | * 项目常量 5 | */ 6 | public final class ProjectConstant { 7 | public static final String BASE_PACKAGE = "com.rogge.order";//项目基础包名称,根据自己公司的项目修改 8 | public static final String COMMON_PACKAGE = "com.rogge.common";//项目基础包名称,根据自己公司的项目修改 9 | 10 | public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model";//Model所在包 11 | public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".mapper";//Mapper所在包 12 | public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//Service所在包 13 | public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//ServiceImpl所在包 14 | public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web";//Controller所在包 15 | 16 | public static final String MAPPER_INTERFACE_REFERENCE = COMMON_PACKAGE + ".core.Mapper";//Mapper插件基础接口的完全限定名 17 | } 18 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/conf/WebMvcConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.conf; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.SerializerFeature; 5 | import com.alibaba.fastjson.support.config.FastJsonConfig; 6 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4; 7 | import com.rogge.common.core.ApiResponse; 8 | import com.rogge.common.core.ResponseCode; 9 | import com.rogge.common.core.ServiceException; 10 | import org.apache.ibatis.exceptions.TooManyResultsException; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.http.converter.HttpMessageConverter; 15 | import org.springframework.web.method.HandlerMethod; 16 | import org.springframework.web.servlet.HandlerExceptionResolver; 17 | import org.springframework.web.servlet.ModelAndView; 18 | import org.springframework.web.servlet.NoHandlerFoundException; 19 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 20 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 21 | 22 | import javax.servlet.ServletException; 23 | import javax.servlet.http.HttpServletRequest; 24 | import javax.servlet.http.HttpServletResponse; 25 | import java.io.IOException; 26 | import java.nio.charset.Charset; 27 | import java.util.List; 28 | 29 | /** 30 | * [Description] 31 | *

32 | * [How to use] 33 | *

34 | * [Tips] 35 | * 36 | * @author Created by Rogge on 2017/10/6 0006. 37 | * @since 1.0.0 38 | */ 39 | @Configuration 40 | public class WebMvcConfigurer extends WebMvcConfigurerAdapter { 41 | private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class); 42 | 43 | //使用阿里 FastJson 作为JSON MessageConverter 44 | @Override 45 | public void configureMessageConverters(List> converters) { 46 | FastJsonHttpMessageConverter4 converter = new FastJsonHttpMessageConverter4(); 47 | FastJsonConfig config = new FastJsonConfig(); 48 | config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,//保留空的字段 49 | SerializerFeature.WriteNullStringAsEmpty,//String null -> "" 50 | SerializerFeature.WriteEnumUsingToString,//使枚举返回ordinal 51 | SerializerFeature.WriteNullNumberAsZero);//Number null -> 0 52 | converter.setFastJsonConfig(config); 53 | converter.setDefaultCharset(Charset.forName("UTF-8")); 54 | converters.add(converter); 55 | } 56 | 57 | //统一异常处理 58 | @Override 59 | public void configureHandlerExceptionResolvers(List exceptionResolvers) { 60 | exceptionResolvers.add(new HandlerExceptionResolver() { 61 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { 62 | ApiResponse lApiResponse = new ApiResponse(); 63 | if (e instanceof ServiceException) {//业务失败的异常,如“账号或密码错误” 64 | lApiResponse.setCode(ResponseCode.Base.ERROR); 65 | lApiResponse.setMsg(e.getMessage()); 66 | logger.info(e.getMessage()); 67 | } else if (e instanceof NoHandlerFoundException) { 68 | lApiResponse.setCode(ResponseCode.Base.API_NO_EXISTS); 69 | lApiResponse.setMsg("接口 [" + request.getRequestURI() + "] 不存在"); 70 | } else if (e instanceof ServletException) { 71 | lApiResponse.setCode(ResponseCode.Base.ERROR); 72 | lApiResponse.setMsg(e.getMessage()); 73 | } else if (e.getCause() instanceof TooManyResultsException) { 74 | lApiResponse = ApiResponse.creatFail(ResponseCode.Base.TOO_MANY_EXCEP); 75 | } else { 76 | lApiResponse.setCode(ResponseCode.Base.API_ERR); 77 | lApiResponse.setMsg("接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员"); 78 | String message; 79 | if (handler instanceof HandlerMethod) { 80 | HandlerMethod handlerMethod = (HandlerMethod) handler; 81 | message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s", 82 | request.getRequestURI(), 83 | handlerMethod.getBean().getClass().getName(), 84 | handlerMethod.getMethod().getName(), 85 | e.getMessage()); 86 | } else { 87 | message = e.getMessage(); 88 | } 89 | logger.error(message, e); 90 | } 91 | responseResult(response, lApiResponse); 92 | return new ModelAndView(); 93 | } 94 | 95 | }); 96 | } 97 | 98 | //解决跨域问题 99 | @Override 100 | public void addCorsMappings(CorsRegistry registry) { 101 | //registry.addMapping("/**"); 102 | } 103 | 104 | private void responseResult(HttpServletResponse response, ApiResponse apiResponse) { 105 | response.setCharacterEncoding("UTF-8"); 106 | response.setHeader("Content-type", "application/json;charset=UTF-8"); 107 | response.setStatus(200); 108 | try { 109 | response.getWriter().write(JSON.toJSONString(apiResponse, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteEnumUsingToString)); 110 | } catch (IOException ex) { 111 | logger.error(ex.getMessage()); 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/feign/UserFeign.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.feign; 2 | 3 | import com.rogge.common.model.User; 4 | import org.springframework.cloud.netflix.feign.FeignClient; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | 9 | /** 10 | * [Description] 11 | *

12 | * [How to use] 13 | *

14 | * [Tips] 15 | * 16 | * @author Created by Rogge on 2017/11/4 0004. 17 | * @since 1.0.0 18 | */ 19 | @FeignClient(name = "user-module", fallback = UserFeign.UserFeignFallback.class) 20 | public interface UserFeign { 21 | @RequestMapping("/detail") 22 | User detail(@RequestParam("id") Long id); 23 | 24 | @Component 25 | class UserFeignFallback implements UserFeign { 26 | 27 | @Override 28 | public User detail(Long id) { 29 | User lUser = new User(); 30 | lUser.setUsername("请求个人数据失败"); 31 | return lUser; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/mapper/OrderMapper.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.mapper; 2 | 3 | import com.rogge.common.core.Mapper; 4 | import com.rogge.order.model.Order; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.List; 9 | 10 | @Repository 11 | public interface OrderMapper extends Mapper { 12 | List selectOrderByUserName(String userName); 13 | } -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/model/Order.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.model; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "t_order") 6 | public class Order { 7 | @Id 8 | @Column(name = "order_id") 9 | private Long orderId; 10 | 11 | @Column(name = "user_id") 12 | private Long userId; 13 | 14 | @Column(name = "product_id") 15 | private Long productId; 16 | 17 | @Column(name = "product_name") 18 | private String productName; 19 | 20 | @Column(name = "order_user_name") 21 | private String orderUserName; 22 | 23 | /** 24 | * @return order_id 25 | */ 26 | public Long getOrderId() { 27 | return orderId; 28 | } 29 | 30 | /** 31 | * @param orderId 32 | */ 33 | public void setOrderId(Long orderId) { 34 | this.orderId = orderId; 35 | } 36 | 37 | /** 38 | * @return product_id 39 | */ 40 | public Long getProductId() { 41 | return productId; 42 | } 43 | 44 | /** 45 | * @param productId 46 | */ 47 | public void setProductId(Long productId) { 48 | this.productId = productId; 49 | } 50 | 51 | /** 52 | * @return product_name 53 | */ 54 | public String getProductName() { 55 | return productName; 56 | } 57 | 58 | /** 59 | * @param productName 60 | */ 61 | public void setProductName(String productName) { 62 | this.productName = productName; 63 | } 64 | 65 | /** 66 | * @return order_user_name 67 | */ 68 | public String getOrderUserName() { 69 | return orderUserName; 70 | } 71 | 72 | /** 73 | * @param orderUserName 74 | */ 75 | public void setOrderUserName(String orderUserName) { 76 | this.orderUserName = orderUserName; 77 | } 78 | 79 | public Long getUserId() { 80 | return userId; 81 | } 82 | 83 | public void setUserId(Long userId) { 84 | this.userId = userId; 85 | } 86 | } -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.service; 2 | 3 | 4 | import com.rogge.common.core.Service; 5 | import com.rogge.order.model.Order; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * [Description] 11 | *

12 | * [How to use] 13 | *

14 | * [Tips] 15 | * 16 | * @author Created by Rogge on 2017/11/01 17 | * @since 1.0.0 18 | */ 19 | public interface OrderService extends Service { 20 | List getOrderByUserName(String userName); 21 | } 22 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/service/impl/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.service.impl; 2 | 3 | import com.rogge.common.core.AbstractService; 4 | import com.rogge.order.mapper.OrderMapper; 5 | import com.rogge.order.model.Order; 6 | import com.rogge.order.service.OrderService; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.List; 12 | 13 | 14 | /** 15 | * [Description] 16 | *

17 | * [How to use] 18 | *

19 | * [Tips] 20 | * 21 | * @author Created by Rogge on 2017/11/01 22 | * @since 1.0.0 23 | */ 24 | @Service 25 | @Transactional 26 | public class OrderServiceImpl extends AbstractService implements OrderService { 27 | @Resource 28 | private OrderMapper orderMapper; 29 | 30 | @Override 31 | public List getOrderByUserName(String userName) { 32 | return orderMapper.selectOrderByUserName(userName); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /order-module/src/main/java/com/rogge/order/web/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order.web; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 6 | import com.rogge.common.core.ApiResponse; 7 | import com.rogge.common.core.BaseController; 8 | import com.rogge.common.core.ResponseCode; 9 | import com.rogge.common.model.User; 10 | import com.rogge.order.feign.UserFeign; 11 | import com.rogge.order.model.Order; 12 | import com.rogge.order.service.OrderService; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Value; 16 | import org.springframework.cloud.context.config.annotation.RefreshScope; 17 | import org.springframework.web.bind.annotation.GetMapping; 18 | import org.springframework.web.bind.annotation.PostMapping; 19 | import org.springframework.web.bind.annotation.RequestParam; 20 | import org.springframework.web.bind.annotation.RestController; 21 | import org.springframework.web.client.RestTemplate; 22 | 23 | import javax.annotation.Resource; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | /** 29 | * [Description] 30 | *

31 | * [How to use] 32 | *

33 | * [Tips] 34 | * 35 | * @author Created by Rogge on 2017/11/01 36 | * @since 1.0.0 37 | */ 38 | @RefreshScope 39 | @RestController 40 | public class OrderController extends BaseController { 41 | private final Logger logger = LoggerFactory.getLogger(OrderController.class); 42 | 43 | @Resource 44 | private OrderService orderService; 45 | 46 | @Resource 47 | private RestTemplate mRestTemplate; 48 | 49 | @Resource 50 | private UserFeign mUserFeign; 51 | 52 | @Value("${person.name}") 53 | String name; 54 | 55 | @PostMapping("/add") 56 | public ApiResponse add(Order order) { 57 | orderService.save(order); 58 | return ApiResponse.creatSuccess(); 59 | } 60 | 61 | @PostMapping("/delete") 62 | public ApiResponse delete(@RequestParam Integer id) { 63 | orderService.deleteById(id); 64 | return ApiResponse.creatSuccess(); 65 | } 66 | 67 | @PostMapping("/update") 68 | public ApiResponse update(Order order) { 69 | orderService.update(order); 70 | return ApiResponse.creatSuccess(); 71 | } 72 | 73 | @PostMapping("/detail") 74 | public ApiResponse detail(@RequestParam Integer id) { 75 | Order order = orderService.findById(id); 76 | return ApiResponse.creatSuccess(order); 77 | } 78 | 79 | @GetMapping("/list") 80 | public ApiResponse list(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size) { 81 | PageHelper.startPage(page, size); 82 | List list = orderService.findAll(); 83 | PageInfo pageInfo = new PageInfo(list); 84 | return ApiResponse.creatSuccess(pageInfo); 85 | } 86 | 87 | /** 88 | * 测试mRestTemplate 89 | * 90 | * @param userId 91 | * @return 92 | */ 93 | @GetMapping("/getOrderByUserId") 94 | @HystrixCommand(fallbackMethod = "getOrderByUserNameError") 95 | public ApiResponse getOrderByUserId(@RequestParam("userId") Long userId) { 96 | // TODO: 2017/11/7 0007 by Rogge RestTemplate没有做session透传 所以会在拦截器失败,如需调用去掉登录拦截器即可 97 | System.out.println("==========" + name); 98 | Map map = new HashMap<>(); 99 | map.put("userId", userId); 100 | User lUser = mRestTemplate.getForObject("http://user-module/detail?id={userId}", User.class,map); 101 | String userName = lUser.getUsername(); 102 | List lOrders = orderService.getOrderByUserName(userName); 103 | return ApiResponse.creatSuccess(lOrders); 104 | } 105 | 106 | /** 107 | * 测试feign 108 | * 109 | * @param userId 110 | * @return 111 | */ 112 | @GetMapping("/getOrderByUserIdV2") 113 | @HystrixCommand(fallbackMethod = "getOrderByUserNameError") 114 | public ApiResponse getOrderByUserIdV2(@RequestParam("userId") Long userId) { 115 | User lUser = mUserFeign.detail(userId); 116 | String userName = lUser.getUsername(); 117 | List lOrders = orderService.getOrderByUserName(userName); 118 | return ApiResponse.creatSuccess(lOrders); 119 | } 120 | 121 | /** 122 | * 测试session透传 需要先调用user模块的登录 123 | * 124 | * @return 125 | */ 126 | @GetMapping("/getOrderByUserIdV3") 127 | public ApiResponse getOrderByUserIdV3() { 128 | User lUser = mSessionUserInfo.getCurrentSessionUser(User.class); 129 | String userName = lUser.getUsername(); 130 | List lOrders = orderService.getOrderByUserName(userName); 131 | return ApiResponse.creatSuccess(lOrders); 132 | } 133 | 134 | public ApiResponse getOrderByUserNameError(Long userId) { 135 | return ApiResponse.creatFail(ResponseCode.Base.API_ERR); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /order-module/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: order-module 4 | cloud: 5 | config: 6 | uri: http://localhost:8089/ 7 | name: order-module 8 | profile: dev 9 | label: master 10 | -------------------------------------------------------------------------------- /order-module/src/main/resources/mapper/OrderMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | -------------------------------------------------------------------------------- /order-module/src/main/resources/order-module-dev.yml: -------------------------------------------------------------------------------- 1 | person: 2 | name: wulei 3 | 4 | hosts: 5 | user-eureka: http://localhost:8089 6 | 7 | server: 8 | port: 8083 9 | 10 | spring: 11 | application: 12 | name: order-module 13 | output: 14 | ansi: 15 | enabled: always #多彩log 16 | 17 | hystrix: 18 | command: 19 | default: 20 | execution: 21 | isolation: 22 | strategy: SEMAPHORE 23 | 24 | management: 25 | security: 26 | enabled: false 27 | 28 | logging: 29 | level: 30 | com.rogge: debug 31 | file: ./logs/order.log 32 | root: info 33 | 34 | eureka: 35 | client: 36 | serviceUrl: 37 | defaultZone: ${hosts.user-eureka}/eureka/ 38 | instance: 39 | preferIpAddress: true 40 | instance-id: ${spring.application.name}:${server.port} 41 | -------------------------------------------------------------------------------- /order-module/src/test/java/com/rogge/order/OrderModuleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.rogge.order; 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 OrderModuleApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.rogge 7 | scloud 8 | 0.0.1-SNAPSHOT 9 | pom 10 | 11 | scloud 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.8.RELEASE 18 | 19 | 20 | 21 | 22 | command-module 23 | user-module 24 | common-module 25 | order-module 26 | discovery-module 27 | gateway-service 28 | 29 | 30 | 31 | UTF-8 32 | UTF-8 33 | 1.8 34 | Dalston.SR4 35 | 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-test 46 | test 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-web 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-starter-jdbc 57 | 58 | 59 | 60 | org.springframework.cloud 61 | spring-cloud-starter-eureka 62 | 63 | 64 | 65 | 66 | commons-codec 67 | commons-codec 68 | 69 | 70 | org.apache.commons 71 | commons-lang3 72 | 3.5 73 | 74 | 75 | com.google.guava 76 | guava 77 | 22.0 78 | 79 | 80 | 81 | 82 | mysql 83 | mysql-connector-java 84 | 5.1.40 85 | runtime 86 | 87 | 88 | 89 | org.mybatis 90 | mybatis-spring 91 | 1.3.0 92 | 93 | 94 | org.mybatis 95 | mybatis 96 | 3.2.8 97 | 98 | 99 | tk.mybatis 100 | mapper 101 | 3.4.0 102 | 103 | 104 | com.github.pagehelper 105 | pagehelper 106 | 4.1.6 107 | 108 | 109 | 110 | 111 | com.alibaba 112 | fastjson 113 | 1.2.22 114 | 115 | 116 | 117 | com.alibaba 118 | druid-spring-boot-starter 119 | 1.1.2 120 | 121 | 122 | 123 | 124 | org.freemarker 125 | freemarker 126 | 2.3.23 127 | 128 | 129 | org.mybatis.generator 130 | mybatis-generator-core 131 | 1.3.5 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | org.springframework.cloud 140 | spring-cloud-dependencies 141 | ${spring-cloud.version} 142 | pom 143 | import 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | org.springframework.boot 152 | spring-boot-maven-plugin 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /sql/command.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA IF EXISTS rogge; 2 | CREATE SCHEMA IF NOT EXISTS rogge; 3 | USE rogge; 4 | SET FOREIGN_KEY_CHECKS=0; 5 | 6 | -- ---------------------------- 7 | -- Table structure for command 8 | -- ---------------------------- 9 | DROP TABLE IF EXISTS `command`; 10 | CREATE TABLE `command` ( 11 | `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 12 | `NAME` varchar(16) DEFAULT NULL COMMENT '指令名称', 13 | `DESCRIPTION` varchar(32) DEFAULT NULL COMMENT '描述', 14 | PRIMARY KEY (`ID`) 15 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; 16 | 17 | -- ---------------------------- 18 | -- Records of command 19 | -- ---------------------------- 20 | INSERT INTO `command` VALUES ('1', '查看', '精彩内容'); 21 | INSERT INTO `command` VALUES ('2', '段子', '精彩段子'); 22 | INSERT INTO `command` VALUES ('3', '新闻', '今日头条'); 23 | INSERT INTO `command` VALUES ('4', '娱乐', '娱乐新闻'); 24 | INSERT INTO `command` VALUES ('5', '电影', '近日上映大片'); 25 | INSERT INTO `command` VALUES ('6', '彩票', '中奖号码'); 26 | -------------------------------------------------------------------------------- /sql/command_content.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA IF EXISTS rogge; 2 | CREATE SCHEMA IF NOT EXISTS rogge; 3 | USE rogge; 4 | SET FOREIGN_KEY_CHECKS=0; 5 | 6 | -- ---------------------------- 7 | -- Table structure for command_content 8 | -- ---------------------------- 9 | DROP TABLE IF EXISTS `command_content`; 10 | CREATE TABLE `command_content` ( 11 | `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 12 | `CONTENT` varchar(255) DEFAULT NULL COMMENT '指令内容', 13 | `COMMAND_ID` int(11) NOT NULL COMMENT '指令主键', 14 | PRIMARY KEY (`ID`) 15 | ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8; 16 | 17 | -- ---------------------------- 18 | -- Records of command_content 19 | -- ---------------------------- 20 | INSERT INTO `command_content` VALUES ('1', '查看1', '1'); 21 | INSERT INTO `command_content` VALUES ('2', '查看2', '1'); 22 | INSERT INTO `command_content` VALUES ('3', '查看3', '1'); 23 | INSERT INTO `command_content` VALUES ('4', '查看4', '1'); 24 | INSERT INTO `command_content` VALUES ('5', '查看5', '1'); 25 | INSERT INTO `command_content` VALUES ('6', '查看6', '1'); 26 | INSERT INTO `command_content` VALUES ('7', '段子1', '2'); 27 | INSERT INTO `command_content` VALUES ('8', '段子2', '2'); 28 | INSERT INTO `command_content` VALUES ('9', '段子3', '2'); 29 | INSERT INTO `command_content` VALUES ('10', '段子4', '2'); 30 | INSERT INTO `command_content` VALUES ('11', '段子5', '2'); 31 | INSERT INTO `command_content` VALUES ('12', '段子6', '2'); 32 | INSERT INTO `command_content` VALUES ('13', '批量插入0', '4'); 33 | INSERT INTO `command_content` VALUES ('14', '批量插入1', '4'); 34 | INSERT INTO `command_content` VALUES ('15', '批量插入2', '4'); 35 | INSERT INTO `command_content` VALUES ('16', '批量插入3', '4'); 36 | INSERT INTO `command_content` VALUES ('17', '批量插入4', '4'); 37 | -------------------------------------------------------------------------------- /sql/order_0.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA IF EXISTS order_0; 2 | CREATE SCHEMA IF NOT EXISTS order_0; 3 | USE order_0; 4 | SET FOREIGN_KEY_CHECKS=0; 5 | 6 | -- ---------------------------- 7 | -- Table structure for order 8 | -- ---------------------------- 9 | DROP TABLE IF EXISTS `t_order_0`; 10 | CREATE TABLE `t_order_0` ( 11 | `order_id` bigint(20) NOT NULL AUTO_INCREMENT, 12 | `user_id` bigint(20) NOT NULL, 13 | `product_id` bigint(20) NOT NULL, 14 | `product_name` varchar(30) NOT NULL, 15 | `order_user_name` varchar(20) NOT NULL, 16 | PRIMARY KEY (`order_id`) 17 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='订单'; 18 | 19 | DROP TABLE IF EXISTS `t_order_1`; 20 | CREATE TABLE `t_order_1` ( 21 | `order_id` bigint(20) NOT NULL AUTO_INCREMENT, 22 | `user_id` bigint(20) NOT NULL, 23 | `product_id` bigint(20) NOT NULL, 24 | `product_name` varchar(30) NOT NULL, 25 | `order_user_name` varchar(20) NOT NULL, 26 | PRIMARY KEY (`order_id`) 27 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='订单'; 28 | 29 | -- ---------------------------- 30 | -- Records of order 31 | -- ---------------------------- 32 | -- INSERT INTO `order` VALUES ('1', '10', '1', '雪地靴', '吴雷'); 33 | -- INSERT INTO `order` VALUES ('2', '11', '2', '篮球', '吴雷'); 34 | -- INSERT INTO `order` VALUES ('3', '12', '3', '帽子', '李四'); 35 | -- INSERT INTO `order` VALUES ('4', '13', '4', '足球', '吴雷'); 36 | -- INSERT INTO `order` VALUES ('5', '14', '1', '雪地靴', '张三'); 37 | -- INSERT INTO `order` VALUES ('6', '15', '5', '羽毛球', '张三'); 38 | -------------------------------------------------------------------------------- /sql/order_1.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA IF EXISTS order_1; 2 | CREATE SCHEMA IF NOT EXISTS order_1; 3 | USE order_1; 4 | SET FOREIGN_KEY_CHECKS=0; 5 | 6 | -- ---------------------------- 7 | -- Table structure for order 8 | -- ---------------------------- 9 | DROP TABLE IF EXISTS `t_order_0`; 10 | CREATE TABLE `t_order_0` ( 11 | `order_id` bigint(20) NOT NULL AUTO_INCREMENT, 12 | `user_id` bigint(20) NOT NULL, 13 | `product_id` bigint(20) NOT NULL, 14 | `product_name` varchar(30) NOT NULL, 15 | `order_user_name` varchar(20) NOT NULL, 16 | PRIMARY KEY (`order_id`) 17 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='订单'; 18 | 19 | DROP TABLE IF EXISTS `t_order_1`; 20 | CREATE TABLE `t_order_1` ( 21 | `order_id` bigint(20) NOT NULL AUTO_INCREMENT, 22 | `user_id` bigint(20) NOT NULL, 23 | `product_id` bigint(20) NOT NULL, 24 | `product_name` varchar(30) NOT NULL, 25 | `order_user_name` varchar(20) NOT NULL, 26 | PRIMARY KEY (`order_id`) 27 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='订单'; 28 | 29 | INSERT INTO `t_order_1` VALUES (1, 1, 1, 'MYSQL 高可用', '吴雷'); 30 | INSERT INTO `t_order_1` VALUES (3, 1, 1, 'MYSQL 高可用', '吴雷'); 31 | INSERT INTO `t_order_1` VALUES (9, 3, 3, 'Thinking In Java', '吴雷'); 32 | INSERT INTO `t_order_1` VALUES (11, 3, 3, 'Thinking In Java', '吴雷'); 33 | INSERT INTO `t_order_1` VALUES (17, 5, 5, 'JavaScript', '吴雷'); 34 | INSERT INTO `t_order_1` VALUES (19, 5, 5, 'JavaScript', '吴雷'); 35 | -------------------------------------------------------------------------------- /sql/user.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA IF EXISTS rogge; 2 | CREATE SCHEMA IF NOT EXISTS rogge; 3 | USE rogge; 4 | 5 | SET FOREIGN_KEY_CHECKS=0; 6 | 7 | -- ---------------------------- 8 | -- Table structure for user 9 | -- ---------------------------- 10 | DROP TABLE IF EXISTS `user`; 11 | CREATE TABLE `user` ( 12 | `id` int(11) NOT NULL AUTO_INCREMENT, 13 | `username` varchar(255) NOT NULL, 14 | `password` varchar(255) NOT NULL, 15 | `nick_name` varchar(255) DEFAULT NULL, 16 | `sex` int(1) DEFAULT NULL, 17 | `register_date` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, 18 | `email` varchar(255) NOT NULL, 19 | `pass_word` varchar(255) NOT NULL, 20 | `reg_time` varchar(255) NOT NULL, 21 | `user_name` varchar(255) NOT NULL, 22 | PRIMARY KEY (`id`) 23 | ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; 24 | 25 | -- ---------------------------- 26 | -- Records of user 27 | -- ---------------------------- 28 | INSERT INTO `user` VALUES ('1', '89921218@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆', '1', '2017-06-23 14:24:23', '', '', '', ''); 29 | INSERT INTO `user` VALUES ('2', '2@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-2', '1', '2017-06-23 14:24:23', '', '', '', ''); 30 | INSERT INTO `user` VALUES ('3', '张三', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-3', '1', '2017-11-01 20:54:26', '', '', '', ''); 31 | INSERT INTO `user` VALUES ('4', '李四', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-4', '1', '2017-11-01 20:54:26', '', '', '', ''); 32 | INSERT INTO `user` VALUES ('5', '吴雷', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-5', '1', '2017-11-01 20:54:26', '', '', '', ''); 33 | INSERT INTO `user` VALUES ('6', '6@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-6', '1', '2017-06-23 14:24:23', '', '', '', ''); 34 | INSERT INTO `user` VALUES ('7', '7@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-7', '1', '2017-06-23 14:24:23', '', '', '', ''); 35 | INSERT INTO `user` VALUES ('8', '8@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-8', '1', '2017-06-23 14:24:23', '', '', '', ''); 36 | INSERT INTO `user` VALUES ('9', '9@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-9', '1', '2017-06-23 14:24:23', '', '', '', ''); 37 | INSERT INTO `user` VALUES ('10', '10@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-10', '1', '2017-06-23 14:24:23', '', '', '', ''); 38 | -------------------------------------------------------------------------------- /user-module/.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/ -------------------------------------------------------------------------------- /user-module/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.rogge.user 7 | user-module 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | user-module 12 | Demo project for Spring Boot 13 | 14 | 15 | com.rogge 16 | scloud 17 | 0.0.1-SNAPSHOT 18 | 19 | 20 | 21 | UTF-8 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | 28 | com.rogge.common 29 | common-module 30 | 0.0.1-SNAPSHOT 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/UmApplication.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.ComponentScan; 9 | import org.springframework.session.data.redis.RedisFlushMode; 10 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 11 | import org.springframework.web.client.RestTemplate; 12 | 13 | @SpringBootApplication 14 | @EnableEurekaClient 15 | @EnableFeignClients 16 | @ComponentScan(basePackages={"com.rogge.common","com.rogge.user"}) 17 | @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) 18 | public class UmApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(UmApplication.class, args); 22 | } 23 | 24 | @Bean 25 | public RestTemplate RestTemplate(){ 26 | return new RestTemplate(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/conf/MybatisConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user.conf; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import org.apache.ibatis.plugin.Interceptor; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | import org.mybatis.spring.SqlSessionFactoryBean; 7 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 11 | import org.springframework.core.io.support.ResourcePatternResolver; 12 | import tk.mybatis.spring.mapper.MapperScannerConfigurer; 13 | 14 | import javax.annotation.Resource; 15 | import javax.sql.DataSource; 16 | import java.util.Properties; 17 | 18 | /** 19 | * [Description] 20 | *

21 | * [How to use] 22 | *

23 | * [Tips] 24 | * 25 | * @author Created by Rogge on 2017/10/6 0006. 26 | * @since 1.0.0 27 | */ 28 | @Configuration 29 | public class MybatisConfigurer { 30 | @Resource 31 | private DataSource dataSource; 32 | 33 | @Bean 34 | public SqlSessionFactory sqlSessionFactoryBean() throws Exception { 35 | SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); 36 | bean.setDataSource(dataSource); 37 | bean.setTypeAliasesPackage(ProjectConstant.MODEL_PACKAGE); 38 | 39 | //分页插件 40 | PageHelper pageHelper = new PageHelper(); 41 | Properties properties = new Properties(); 42 | properties.setProperty("reasonable", "true"); 43 | properties.setProperty("supportMethodsArguments", "true"); 44 | properties.setProperty("returnPageInfo", "check"); 45 | properties.setProperty("params", "count=countSql"); 46 | properties.setProperty("pageSizeZero", "true");//分页尺寸为0时查询所有纪录不再执行分页 47 | pageHelper.setProperties(properties); 48 | 49 | //添加插件 50 | bean.setPlugins(new Interceptor[]{pageHelper}); 51 | 52 | //添加XML目录 53 | ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 54 | bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); 55 | return bean.getObject(); 56 | } 57 | 58 | @Configuration 59 | @AutoConfigureAfter(MybatisConfigurer.class) 60 | public static class MyBatisMapperScannerConfigurer { 61 | 62 | @Bean 63 | public MapperScannerConfigurer mapperScannerConfigurer() { 64 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 65 | mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean"); 66 | mapperScannerConfigurer.setBasePackage(ProjectConstant.MAPPER_PACKAGE); 67 | //配置通用mappers 68 | Properties properties = new Properties(); 69 | properties.setProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE); 70 | properties.setProperty("notEmpty", "false"); 71 | properties.setProperty("IDENTITY", "MYSQL"); 72 | mapperScannerConfigurer.setProperties(properties); 73 | return mapperScannerConfigurer; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/conf/ProjectConstant.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user.conf; 2 | 3 | /** 4 | * 项目常量 5 | */ 6 | public final class ProjectConstant { 7 | public static final String BASE_PACKAGE = "com.rogge.user";//项目基础包名称,根据自己公司的项目修改 8 | public static final String COMMON_PACKAGE = "com.rogge.common";//项目基础包名称,根据自己公司的项目修改 9 | 10 | public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model";//Model所在包 11 | public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".mapper";//Mapper所在包 12 | public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//Service所在包 13 | public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//ServiceImpl所在包 14 | public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web";//Controller所在包 15 | 16 | public static final String MAPPER_INTERFACE_REFERENCE = COMMON_PACKAGE + ".core.Mapper";//Mapper插件基础接口的完全限定名 17 | } 18 | -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/conf/WebMvcConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user.conf; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.SerializerFeature; 5 | import com.alibaba.fastjson.support.config.FastJsonConfig; 6 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4; 7 | import com.rogge.common.core.ApiResponse; 8 | import com.rogge.common.core.ResponseCode; 9 | import com.rogge.common.core.ServiceException; 10 | import org.apache.ibatis.exceptions.TooManyResultsException; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.http.converter.HttpMessageConverter; 15 | import org.springframework.web.method.HandlerMethod; 16 | import org.springframework.web.servlet.HandlerExceptionResolver; 17 | import org.springframework.web.servlet.ModelAndView; 18 | import org.springframework.web.servlet.NoHandlerFoundException; 19 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 20 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 21 | 22 | import javax.servlet.ServletException; 23 | import javax.servlet.http.HttpServletRequest; 24 | import javax.servlet.http.HttpServletResponse; 25 | import java.io.IOException; 26 | import java.nio.charset.Charset; 27 | import java.util.List; 28 | 29 | /** 30 | * [Description] 31 | *

32 | * [How to use] 33 | *

34 | * [Tips] 35 | * 36 | * @author Created by Rogge on 2017/10/6 0006. 37 | * @since 1.0.0 38 | */ 39 | @Configuration 40 | public class WebMvcConfigurer extends WebMvcConfigurerAdapter { 41 | private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class); 42 | 43 | //使用阿里 FastJson 作为JSON MessageConverter 44 | @Override 45 | public void configureMessageConverters(List> converters) { 46 | FastJsonHttpMessageConverter4 converter = new FastJsonHttpMessageConverter4(); 47 | FastJsonConfig config = new FastJsonConfig(); 48 | config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,//保留空的字段 49 | SerializerFeature.WriteNullStringAsEmpty,//String null -> "" 50 | SerializerFeature.WriteEnumUsingToString,//使枚举返回ordinal 51 | SerializerFeature.WriteNullNumberAsZero);//Number null -> 0 52 | converter.setFastJsonConfig(config); 53 | converter.setDefaultCharset(Charset.forName("UTF-8")); 54 | converters.add(converter); 55 | } 56 | 57 | //统一异常处理 58 | @Override 59 | public void configureHandlerExceptionResolvers(List exceptionResolvers) { 60 | exceptionResolvers.add(new HandlerExceptionResolver() { 61 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { 62 | ApiResponse lApiResponse = new ApiResponse(); 63 | if (e instanceof ServiceException) {//业务失败的异常,如“账号或密码错误” 64 | lApiResponse.setCode(ResponseCode.Base.ERROR); 65 | lApiResponse.setMsg(e.getMessage()); 66 | logger.info(e.getMessage()); 67 | } else if (e instanceof NoHandlerFoundException) { 68 | lApiResponse.setCode(ResponseCode.Base.API_NO_EXISTS); 69 | lApiResponse.setMsg("接口 [" + request.getRequestURI() + "] 不存在"); 70 | } else if (e instanceof ServletException) { 71 | lApiResponse.setCode(ResponseCode.Base.ERROR); 72 | lApiResponse.setMsg(e.getMessage()); 73 | } else if (e.getCause() instanceof TooManyResultsException) { 74 | lApiResponse = ApiResponse.creatFail(ResponseCode.Base.TOO_MANY_EXCEP); 75 | } else { 76 | lApiResponse.setCode(ResponseCode.Base.API_ERR); 77 | lApiResponse.setMsg("接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员"); 78 | String message; 79 | if (handler instanceof HandlerMethod) { 80 | HandlerMethod handlerMethod = (HandlerMethod) handler; 81 | message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s", 82 | request.getRequestURI(), 83 | handlerMethod.getBean().getClass().getName(), 84 | handlerMethod.getMethod().getName(), 85 | e.getMessage()); 86 | } else { 87 | message = e.getMessage(); 88 | } 89 | logger.error(message, e); 90 | } 91 | responseResult(response, lApiResponse); 92 | return new ModelAndView(); 93 | } 94 | 95 | }); 96 | } 97 | 98 | //解决跨域问题 99 | @Override 100 | public void addCorsMappings(CorsRegistry registry) { 101 | //registry.addMapping("/**"); 102 | } 103 | 104 | private void responseResult(HttpServletResponse response, ApiResponse apiResponse) { 105 | response.setCharacterEncoding("UTF-8"); 106 | response.setHeader("Content-type", "application/json;charset=UTF-8"); 107 | response.setStatus(200); 108 | try { 109 | response.getWriter().write(JSON.toJSONString(apiResponse, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteEnumUsingToString)); 110 | } catch (IOException ex) { 111 | logger.error(ex.getMessage()); 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user.mapper; 2 | 3 | 4 | import com.rogge.common.core.Mapper; 5 | import com.rogge.common.model.User; 6 | import org.springframework.stereotype.Repository; 7 | 8 | @Repository 9 | public interface UserMapper extends Mapper { 10 | } -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user.service; 2 | 3 | 4 | import com.rogge.common.core.Service; 5 | import com.rogge.common.model.User; 6 | 7 | /** 8 | * [Description] 9 | *

10 | * [How to use] 11 | *

12 | * [Tips] 13 | * 14 | * @author Created by Rogge on 2017/10/07 15 | * @since 1.0.0 16 | */ 17 | public interface UserService extends Service { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user.service.impl; 2 | 3 | import com.rogge.common.core.AbstractService; 4 | import com.rogge.common.model.User; 5 | import com.rogge.user.mapper.UserMapper; 6 | import com.rogge.user.service.UserService; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import javax.annotation.Resource; 11 | 12 | 13 | /** 14 | * [Description] 15 | *

16 | * [How to use] 17 | *

18 | * [Tips] 19 | * 20 | * @author Created by Rogge on 2017/10/07 21 | * @since 1.0.0 22 | */ 23 | @Service 24 | @Transactional 25 | public class UserServiceImpl extends AbstractService implements UserService { 26 | @Resource 27 | private UserMapper userMapper; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /user-module/src/main/java/com/rogge/user/web/UserController.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user.web; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.rogge.common.core.ApiResponse; 6 | import com.rogge.common.core.BaseController; 7 | import com.rogge.common.model.User; 8 | import com.rogge.user.service.UserService; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | import javax.annotation.Resource; 17 | import javax.servlet.http.HttpSession; 18 | import java.util.List; 19 | 20 | /** 21 | * [Description] 22 | *

23 | * [How to use] 24 | *

25 | * [Tips] 26 | * 27 | * @author Created by Rogge on 2017/10/07 28 | * @since 1.0.0 29 | */ 30 | @RestController 31 | public class UserController extends BaseController { 32 | private final Logger logger = LoggerFactory.getLogger(UserController.class); 33 | 34 | @Resource 35 | private UserService userService; 36 | 37 | @PostMapping("/add") 38 | public ApiResponse add(User user) { 39 | userService.save(user); 40 | return ApiResponse.creatSuccess(); 41 | } 42 | 43 | @PostMapping("/delete") 44 | public ApiResponse delete(@RequestParam Integer id) { 45 | userService.deleteById(id); 46 | return ApiResponse.creatSuccess(); 47 | } 48 | 49 | @PostMapping("/update") 50 | public ApiResponse update(User user) { 51 | userService.update(user); 52 | return ApiResponse.creatSuccess(); 53 | } 54 | 55 | @GetMapping("/login") 56 | public ApiResponse login(HttpSession session, @RequestParam Integer id) { 57 | User lUser = userService.findById(id); 58 | mSessionUserInfo.setSessionUser(session, lUser); 59 | return ApiResponse.creatSuccess((Object) "登录成功"); 60 | } 61 | 62 | @GetMapping("/detail") 63 | public User detail(@RequestParam Integer id) { 64 | return userService.findById(id); 65 | } 66 | 67 | @GetMapping("/list") 68 | public ApiResponse list(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size) { 69 | PageHelper.startPage(page, size); 70 | List list = userService.findAll(); 71 | PageInfo pageInfo = new PageInfo(list); 72 | return ApiResponse.creatSuccess(pageInfo); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /user-module/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8085 3 | 4 | spring: 5 | application: 6 | name: user-module 7 | datasource: 8 | type: com.alibaba.druid.pool.DruidDataSource 9 | driver-class-name: com.mysql.jdbc.Driver 10 | url: jdbc:mysql://127.0.0.1:3306/rogge?autoReconnect=true&useUnicode=true&characterEncoding=utf8 11 | username: root 12 | password: 123456 13 | output: 14 | ansi: 15 | enabled: always #多彩log 16 | 17 | logging: 18 | level: 19 | com.rogge: debug 20 | file: ./logs/um.log 21 | root: info 22 | 23 | eureka: 24 | client: 25 | serviceUrl: 26 | defaultZone: http://localhost:8089/eureka/ 27 | instance: 28 | preferIpAddress: true 29 | instance-id: ${spring.application.name}:${server.port} 30 | 31 | -------------------------------------------------------------------------------- /user-module/src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /user-module/src/test/java/com/rogge/user/UmApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.rogge.user; 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 UmApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------