├── src └── main │ ├── webapp │ ├── index.jsp │ └── WEB-INF │ │ └── web.xml │ ├── java │ └── com │ │ └── artisan │ │ ├── dao │ │ ├── FileMapper.java │ │ ├── MenuMapper.java │ │ ├── PageMapper.java │ │ ├── RoleMapper.java │ │ ├── UserRoleMapper.java │ │ ├── OperationMapper.java │ │ ├── UserGroupMapper.java │ │ ├── PermissionMapper.java │ │ ├── UserGroupRoleMapper.java │ │ ├── UserGroupUserMapper.java │ │ ├── FilePermissionMapper.java │ │ ├── MenuPermissionMapper.java │ │ ├── PagePermissionMapper.java │ │ ├── RolePermissionMapper.java │ │ ├── PermissionOperationMapper.java │ │ └── UserMapper.java │ │ ├── common │ │ ├── constant │ │ │ ├── StatusCode.java │ │ │ └── Constants.java │ │ ├── utils │ │ │ ├── MyMapper.java │ │ │ ├── WebContextUtil.java │ │ │ ├── Base64Util.java │ │ │ ├── VerificationUtil.java │ │ │ ├── JsonUtils.java │ │ │ ├── DateUtils.java │ │ │ └── StringUtils.java │ │ ├── annotation │ │ │ └── IgnoreSecurity.java │ │ ├── exception │ │ │ └── TokenException.java │ │ ├── config │ │ │ └── SwaggerConfig.java │ │ ├── filter │ │ │ └── CorsFilter.java │ │ └── aspect │ │ │ ├── SecurityAspect.java │ │ │ └── ExceptionAspect.java │ │ ├── handler │ │ ├── BaseHandler.java │ │ ├── HomeHandler.java │ │ └── UserHandler.java │ │ ├── service │ │ ├── IUserService.java │ │ ├── IBaseService.java │ │ └── impl │ │ │ ├── UserServiceImpl.java │ │ │ └── BaseServiceImpl.java │ │ ├── authorization │ │ ├── manager │ │ │ ├── JsonWebTokenManager.java │ │ │ ├── TokenManager.java │ │ │ └── impl │ │ │ │ ├── JsonWebTokenManagerImpl.java │ │ │ │ └── RedisTokenManager.java │ │ └── model │ │ │ └── TokenModel.java │ │ └── pojo │ │ ├── ao │ │ └── DataGridResult.java │ │ ├── qo │ │ └── UserQO.java │ │ ├── vo │ │ ├── ResultBean.java │ │ └── UserVO.java │ │ └── db │ │ ├── PermissionOperation.java │ │ ├── MenuPermission.java │ │ ├── UserRole.java │ │ ├── FilePermission.java │ │ ├── RolePermission.java │ │ ├── PagePermission.java │ │ ├── Role.java │ │ ├── UserGroupRole.java │ │ ├── UserGroupUser.java │ │ ├── Permission.java │ │ ├── Page.java │ │ ├── File.java │ │ ├── UserGroup.java │ │ ├── Menu.java │ │ ├── Operation.java │ │ └── User.java │ └── resources │ ├── config.properties │ ├── mapper │ ├── UserRoleMapper.xml │ ├── RoleMapper.xml │ ├── PageMapper.xml │ ├── RolePermissionMapper.xml │ ├── FilePermissionMapper.xml │ ├── MenuPermissionMapper.xml │ ├── PermissionMapper.xml │ ├── UserGroupRoleMapper.xml │ ├── UserGroupUserMapper.xml │ ├── PagePermissionMapper.xml │ ├── PermissionOperationMapper.xml │ ├── FileMapper.xml │ ├── UserGroupMapper.xml │ ├── MenuMapper.xml │ ├── OperationMapper.xml │ └── UserMapper.xml │ ├── spring │ ├── mybatis-config.xml │ ├── spring-mvc.xml │ └── applicationContext.xml │ ├── log4j.properties │ ├── generator │ └── generatorConfig.xml │ └── code_artisan.sql ├── .gitignore ├── README.md └── pom.xml /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/FileMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.File; 5 | 6 | public interface FileMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/MenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.Menu; 5 | 6 | public interface MenuMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/PageMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.Page; 5 | 6 | public interface PageMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/RoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.Role; 5 | 6 | public interface RoleMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/UserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.UserRole; 5 | 6 | public interface UserRoleMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/OperationMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.Operation; 5 | 6 | public interface OperationMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/UserGroupMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.UserGroup; 5 | 6 | public interface UserGroupMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/PermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.Permission; 5 | 6 | public interface PermissionMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/UserGroupRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.UserGroupRole; 5 | 6 | public interface UserGroupRoleMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/UserGroupUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.UserGroupUser; 5 | 6 | public interface UserGroupUserMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/FilePermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.FilePermission; 5 | 6 | public interface FilePermissionMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/MenuPermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.MenuPermission; 5 | 6 | public interface MenuPermissionMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/PagePermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.PagePermission; 5 | 6 | public interface PagePermissionMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/RolePermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.RolePermission; 5 | 6 | public interface RolePermissionMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/PermissionOperationMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.PermissionOperation; 5 | 6 | public interface PermissionOperationMapper extends MyMapper { 7 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/constant/StatusCode.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.constant; 2 | 3 | /** 4 | * 业务状态码 5 | * @author leeyom 6 | * @date 2017年10月19日 10:41 7 | */ 8 | public interface StatusCode { 9 | int HTTP_SUCCESS = 200; 10 | int HTTP_FAILURE = 500; 11 | } 12 | -------------------------------------------------------------------------------- /.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/ -------------------------------------------------------------------------------- /src/main/java/com/artisan/dao/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.dao; 2 | 3 | import com.artisan.common.utils.MyMapper; 4 | import com.artisan.pojo.db.User; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | public interface UserMapper extends MyMapper { 8 | 9 | User getUser(@Param("userName") String userName, @Param("password") String password); 10 | 11 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/utils/MyMapper.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.utils; 2 | 3 | import tk.mybatis.mapper.common.Mapper; 4 | import tk.mybatis.mapper.common.MySqlMapper; 5 | 6 | /** 7 | * 继承通用的Mapper,方便后期自己的扩展 8 | * @author Leeyom Wang 9 | * @date 2017年10月26日 11:25 10 | */ 11 | public interface MyMapper extends Mapper, MySqlMapper { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/annotation/IgnoreSecurity.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | 6 | /** 7 | * 自定义注解,标识是否忽略REST安全性检查 8 | * @author leeyom 9 | * @date 2017年10月19日 10:41 10 | */ 11 | @Target(ElementType.METHOD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface IgnoreSecurity { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/handler/BaseHandler.java: -------------------------------------------------------------------------------- 1 | package com.artisan.handler; 2 | 3 | import com.artisan.service.IUserService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Controller; 6 | 7 | /** 8 | * 统一注入service实例 9 | * @author Leeyom Wang 10 | * @date 2017年10月26日 16:14 11 | */ 12 | @Controller 13 | public class BaseHandler { 14 | 15 | @Autowired 16 | IUserService userService; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/service/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.artisan.service; 2 | 3 | import com.artisan.pojo.db.User; 4 | 5 | /** 6 | * User的service接口层 7 | * @author Leeyom Wang 8 | * @date 2017年10月26日 15:14 9 | */ 10 | public interface IUserService extends IBaseService { 11 | 12 | /** 13 | * 根据用户名和密码获取用户信息 14 | * @param userName 15 | * @param password 16 | * @return 17 | */ 18 | User getUser(String userName, String password); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/authorization/manager/JsonWebTokenManager.java: -------------------------------------------------------------------------------- 1 | package com.artisan.authorization.manager; 2 | 3 | public interface JsonWebTokenManager { 4 | 5 | /** 6 | * 创建一个 JWT token 7 | * @param userId 指定用户的id 8 | * @return 生成的token 9 | */ 10 | String createToken(long userId); 11 | 12 | /** 13 | * 检查 JWT token是否有效 14 | * @param token token 15 | * @return 是否有效 16 | */ 17 | boolean checkToken(String token); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/config.properties: -------------------------------------------------------------------------------- 1 | # mysql database 2 | jdbc.user=root 3 | jdbc.password=root 4 | jdbc.driverClass = com.mysql.jdbc.Driver 5 | jdbc.jdbcUrl=jdbc:mysql://127.0.0.1:3306/code_artisan?useSSL=true&characterEncoding=UTF-8 6 | 7 | # redis 8 | redis.host = 192.168.1.225 9 | redis.port = 6379 10 | redis.timeout = 100000 11 | redis.password = Ldm%1910 12 | 13 | # common Mapper 14 | mapper.plugin = tk.mybatis.mapper.generator.MapperPlugin 15 | mapper.Mapper = com.artisan.common.utils.MyMapper -------------------------------------------------------------------------------- /src/main/java/com/artisan/service/IBaseService.java: -------------------------------------------------------------------------------- 1 | package com.artisan.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 通用的Service 9 | * @author leeyom 10 | */ 11 | @Service 12 | public interface IBaseService { 13 | 14 | int deleteByPrimaryKey(Integer id); 15 | 16 | int insert(T record); 17 | 18 | T selectByPrimaryKey(Integer id); 19 | 20 | List selectAll(); 21 | 22 | int updateByPrimaryKey(T record); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/RoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/PageMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/spring/mybatis-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/mapper/RolePermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/FilePermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/MenuPermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/PermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserGroupRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserGroupUserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/PagePermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/PermissionOperationMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/mapper/FileMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/exception/TokenException.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.exception; 2 | 3 | /** 4 | * Token过期时抛出异常 5 | * @author leeyom 6 | * @date 2017年10月19日 10:41 7 | */ 8 | public class TokenException extends RuntimeException { 9 | 10 | private static final long serialVersionUID = 1L; 11 | 12 | private String msg; 13 | 14 | public TokenException(String msg) { 15 | super(); 16 | this.msg = msg; 17 | } 18 | 19 | public String getMsg() { 20 | return msg; 21 | } 22 | 23 | public void setMsg(String msg) { 24 | this.msg = msg; 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /src/main/resources/mapper/UserGroupMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/ao/DataGridResult.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.ao; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 分页结果封装实体 7 | * @author leeyom 8 | */ 9 | public class DataGridResult { 10 | /** 11 | * 总的记录数 12 | */ 13 | Long total; 14 | /** 15 | * 数据集 16 | */ 17 | List rows; 18 | 19 | public Long getTotal() { 20 | return total; 21 | } 22 | 23 | public void setTotal(Long total) { 24 | this.total = total; 25 | } 26 | 27 | public List getRows() { 28 | return rows; 29 | } 30 | 31 | public void setRows(List rows) { 32 | this.rows = rows; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/resources/mapper/MenuMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/constant/Constants.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.constant; 2 | 3 | /** 4 | * 常量 5 | * @author leeyom 6 | * @date 2017年10月19日 10:41 7 | */ 8 | public class Constants { 9 | 10 | /** 11 | * 存储当前登录用户id的字段名 12 | */ 13 | public static final String CURRENT_USER_ID = "CURRENT_USER_ID"; 14 | 15 | /** 16 | * token有效期(小时) 17 | */ 18 | public static final int TOKEN_EXPIRES_HOUR = 2; 19 | 20 | /** 21 | * 存放Token的header字段 22 | */ 23 | public static final String DEFAULT_TOKEN_NAME = "Access-Token"; 24 | 25 | /** 26 | * JWT 加密秘钥 27 | */ 28 | public static final String SECRET_KEY = "57b5f298-3d3a-41ae-b0aa-925be9d57449"; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/utils/WebContextUtil.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.utils; 2 | 3 | import org.springframework.web.context.request.RequestContextHolder; 4 | import org.springframework.web.context.request.ServletRequestAttributes; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | 8 | 9 | /** 10 | * Web上下文工具类 11 | * @author Leeyom Wang 12 | * @date 2017年10月19日 11:51 13 | */ 14 | public class WebContextUtil { 15 | 16 | /** 17 | * 获取HTTP请求 18 | * @return 19 | */ 20 | public static HttpServletRequest getRequest() { 21 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 22 | return request; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/mapper/OperationMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.artisan.service.impl; 2 | 3 | import com.artisan.dao.UserMapper; 4 | import com.artisan.pojo.db.User; 5 | import com.artisan.service.IUserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | * IUserService接口实现类 11 | * @author Leeyom Wang 12 | * @date 2017年10月26日 15:15 13 | */ 14 | @Service("userService") 15 | public class UserServiceImpl extends BaseServiceImpl implements IUserService { 16 | 17 | @Autowired 18 | UserMapper userMapper; 19 | 20 | /** 21 | * 根据用户名和密码获取用户信息 22 | * @param userName 23 | * @param password 24 | * @return 25 | */ 26 | @Override 27 | public User getUser(String userName, String password) { 28 | return userMapper.getUser(userName,password); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/qo/UserQO.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.qo; 2 | 3 | /** 4 | * user查询实体 5 | * @author Leeyom Wang 6 | * @date 2017年10月26日 15:22 7 | */ 8 | public class UserQO { 9 | 10 | /** 11 | * 姓名,查询字段 12 | */ 13 | private String uName; 14 | 15 | /** 16 | * 性别,查询字段 17 | */ 18 | private Integer sex; 19 | 20 | public String getuName() { 21 | return uName; 22 | } 23 | 24 | public void setuName(String uName) { 25 | this.uName = uName; 26 | } 27 | 28 | public Integer getSex() { 29 | return sex; 30 | } 31 | 32 | public void setSex(Integer sex) { 33 | this.sex = sex; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "UserQO{" + 39 | "uName='" + uName + '\'' + 40 | ", sex=" + sex + 41 | '}'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/authorization/manager/TokenManager.java: -------------------------------------------------------------------------------- 1 | package com.artisan.authorization.manager; 2 | 3 | import com.artisan.authorization.model.TokenModel; 4 | 5 | /** 6 | * 对Token进行操作的接口 7 | * @author leeyom 8 | * @date 2017年10月19日 10:41 9 | */ 10 | public interface TokenManager { 11 | 12 | /** 13 | * 创建一个token关联上指定用户 14 | * @param userId 指定用户的id 15 | * @return 生成的token 16 | */ 17 | TokenModel createToken(long userId); 18 | 19 | /** 20 | * 检查token是否有效 21 | * @param model token 22 | * @return 是否有效 23 | */ 24 | boolean checkToken(TokenModel model); 25 | 26 | /** 27 | * 从字符串中解析token 28 | * @param authentication 加密后的字符串 29 | * @return 30 | */ 31 | TokenModel getToken(String authentication); 32 | 33 | /** 34 | * 清除token 35 | * @param userId 登录用户的id 36 | */ 37 | void deleteToken(long userId); 38 | 39 | /** 40 | * 保证一个用户在一个时间段只有一个可用 Token 41 | * @param userId 42 | * @return 43 | */ 44 | boolean hasToken(long userId); 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/vo/ResultBean.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.vo; 2 | 3 | /** 4 | * restful API 接口统一响应值 5 | * @author leeyom 6 | * @date 2017年10月19日 10:57 7 | */ 8 | public class ResultBean { 9 | 10 | /** 11 | * 数据集 12 | */ 13 | private Object data = null; 14 | /** 15 | * 返回信息 16 | */ 17 | private String msg = "Request Success!"; 18 | /** 19 | * 业务自定义状态码 20 | */ 21 | private Integer code = 200; 22 | /** 23 | * 全局附加数据 24 | */ 25 | private Object etxra = null; 26 | 27 | public Object getData() { 28 | return data; 29 | } 30 | 31 | public void setData(Object data) { 32 | this.data = data; 33 | } 34 | 35 | public String getMsg() { 36 | return msg; 37 | } 38 | 39 | public void setMsg(String msg) { 40 | this.msg = msg; 41 | } 42 | 43 | public Integer getCode() { 44 | return code; 45 | } 46 | 47 | public void setCode(Integer code) { 48 | this.code = code; 49 | } 50 | 51 | public Object getEtxra() { 52 | return etxra; 53 | } 54 | 55 | public void setEtxra(Object etxra) { 56 | this.etxra = etxra; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/service/impl/BaseServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.artisan.service.impl; 2 | 3 | import com.artisan.service.IBaseService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import tk.mybatis.mapper.common.Mapper; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 通用的BaseService实现类 11 | * @author Leeyom Wang 12 | * @date 2017年10月26日 12:04 13 | */ 14 | public abstract class BaseServiceImpl implements IBaseService { 15 | 16 | @Autowired 17 | protected Mapper mapper; 18 | 19 | public Mapper getMapper() { 20 | return mapper; 21 | } 22 | 23 | @Override 24 | public int deleteByPrimaryKey(Integer id) { 25 | return mapper.deleteByPrimaryKey(id); 26 | } 27 | 28 | @Override 29 | public int insert(T record) { 30 | return mapper.insert(record); 31 | } 32 | 33 | @Override 34 | public T selectByPrimaryKey(Integer id) { 35 | return mapper.selectByPrimaryKey(id); 36 | } 37 | 38 | @Override 39 | public List selectAll() { 40 | return mapper.selectAll(); 41 | } 42 | 43 | @Override 44 | public int updateByPrimaryKey(T record) { 45 | return mapper.updateByPrimaryKey(record); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/PermissionOperation.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "permission_operation") 6 | public class PermissionOperation { 7 | @Id 8 | @Column(name = "p_id") 9 | private Integer pId; 10 | 11 | @Id 12 | @Column(name = "o_id") 13 | private Integer oId; 14 | 15 | /** 16 | * @return p_id 17 | */ 18 | public Integer getpId() { 19 | return pId; 20 | } 21 | 22 | /** 23 | * @param pId 24 | */ 25 | public void setpId(Integer pId) { 26 | this.pId = pId; 27 | } 28 | 29 | /** 30 | * @return o_id 31 | */ 32 | public Integer getoId() { 33 | return oId; 34 | } 35 | 36 | /** 37 | * @param oId 38 | */ 39 | public void setoId(Integer oId) { 40 | this.oId = oId; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | StringBuilder sb = new StringBuilder(); 46 | sb.append(getClass().getSimpleName()); 47 | sb.append(" ["); 48 | sb.append("Hash = ").append(hashCode()); 49 | sb.append(", pId=").append(pId); 50 | sb.append(", oId=").append(oId); 51 | sb.append("]"); 52 | return sb.toString(); 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | #\u5B9A\u4E49LOG\u8F93\u51FA\u7EA7\u522B 2 | log4j.rootLogger=INFO,Console,File 3 | #\u5B9A\u4E49\u65E5\u5FD7\u8F93\u51FA\u76EE\u7684\u5730\u4E3A\u63A7\u5236\u53F0 4 | log4j.appender.Console=org.apache.log4j.ConsoleAppender 5 | log4j.appender.Console.Target=System.out 6 | #\u53EF\u4EE5\u7075\u6D3B\u5730\u6307\u5B9A\u65E5\u5FD7\u8F93\u51FA\u683C\u5F0F\uFF0C\u4E0B\u9762\u4E00\u884C\u662F\u6307\u5B9A\u5177\u4F53\u7684\u683C\u5F0F 7 | log4j.appender.Console.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n 9 | #\u6587\u4EF6\u5927\u5C0F\u5230\u8FBE\u6307\u5B9A\u5C3A\u5BF8\u7684\u65F6\u5019\u4EA7\u751F\u4E00\u4E2A\u65B0\u7684\u6587\u4EF6 10 | log4j.appender.File=org.apache.log4j.RollingFileAppender 11 | #\u6307\u5B9A\u8F93\u51FA\u76EE\u5F55 12 | log4j.appender.File.File=${catalina.home}/logs/code-artisan.log 13 | #\u5B9A\u4E49\u6587\u4EF6\u6700\u5927\u5927\u5C0F 14 | log4j.appender.File.MaxFileSize=10MB 15 | # \u8F93\u51FA\u6240\u4EE5\u65E5\u5FD7\uFF0C\u5982\u679C\u6362\u6210DEBUG\u8868\u793A\u8F93\u51FADEBUG\u4EE5\u4E0A\u7EA7\u522B\u65E5\u5FD7 16 | log4j.appender.File.Threshold=ALL 17 | log4j.appender.File.layout=org.apache.log4j.PatternLayout 18 | log4j.appender.File.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n -------------------------------------------------------------------------------- /src/main/java/com/artisan/authorization/model/TokenModel.java: -------------------------------------------------------------------------------- 1 | package com.artisan.authorization.model; 2 | 3 | /** 4 | * Token的Model类,可以增加字段提高安全性,例如时间戳、url签名 5 | * @author leeyom 6 | * @date 2017年10月19日 10:41 7 | */ 8 | public class TokenModel { 9 | 10 | /** 11 | * 用户id 12 | */ 13 | private long userId; 14 | 15 | /** 16 | * 随机生成的uuid 17 | */ 18 | private String uuid; 19 | 20 | /** 21 | * 时间戳 22 | */ 23 | private String timestamp; 24 | 25 | public TokenModel(long userId, String uuid, String timestamp) { 26 | this.userId = userId; 27 | this.uuid = uuid; 28 | this.timestamp = timestamp; 29 | } 30 | 31 | public long getUserId() { 32 | return userId; 33 | } 34 | 35 | public void setUserId(long userId) { 36 | this.userId = userId; 37 | } 38 | 39 | public String getUuid() { 40 | return uuid; 41 | } 42 | 43 | public void setUuid(String uuid) { 44 | this.uuid = uuid; 45 | } 46 | 47 | public String getTimestamp() { 48 | return timestamp; 49 | } 50 | 51 | public void setTimestamp(String timestamp) { 52 | this.timestamp = timestamp; 53 | } 54 | 55 | public String getToken() { 56 | return userId + "_" + timestamp + "_" + uuid; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |   6 | LICENSE 7 |   8 | 9 | 10 |

11 | 12 | 13 | # 任务列表 14 | 15 | 任务列表: 16 | 17 | - [x] 项目搭建 18 | - [x] 前后台参数传递约定 19 | - [x] 统一响应结构 20 | - [x] 统一异常处理 21 | - [x] CORS跨域请求处理 22 | - [x] JWT鉴权机制,保证接口安全 23 | - [x] 集成Swagger2,自动生成restful api文档 24 | - [x] 集成通用Mapper、pagehelper分页插件 25 | - [x] Hibernate Vilation参数校验机制 26 | 27 | 28 | # 项目结构 29 | 30 |

31 | 32 |

33 | 34 | # 详细过程 35 | 36 | 更加具体的详细过程可以参考我的文章:[《关于前后端分离的思考和总结》](http://www.leeyom.top/2017/11/04/fontend-backend-separation/),欢迎大家一起探讨! 37 | 38 | # 联系方式 39 | - Email:leeyomwang@qq.com 40 | - qq:635709492 41 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/MenuPermission.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "menu_permission") 6 | public class MenuPermission { 7 | /** 8 | * 菜单主键 9 | */ 10 | @Column(name = "m_id") 11 | private Integer mId; 12 | 13 | /** 14 | * 权限主键 15 | */ 16 | @Column(name = "p_id") 17 | private Integer pId; 18 | 19 | /** 20 | * 获取菜单主键 21 | * 22 | * @return m_id - 菜单主键 23 | */ 24 | public Integer getmId() { 25 | return mId; 26 | } 27 | 28 | /** 29 | * 设置菜单主键 30 | * 31 | * @param mId 菜单主键 32 | */ 33 | public void setmId(Integer mId) { 34 | this.mId = mId; 35 | } 36 | 37 | /** 38 | * 获取权限主键 39 | * 40 | * @return p_id - 权限主键 41 | */ 42 | public Integer getpId() { 43 | return pId; 44 | } 45 | 46 | /** 47 | * 设置权限主键 48 | * 49 | * @param pId 权限主键 50 | */ 51 | public void setpId(Integer pId) { 52 | this.pId = pId; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | StringBuilder sb = new StringBuilder(); 58 | sb.append(getClass().getSimpleName()); 59 | sb.append(" ["); 60 | sb.append("Hash = ").append(hashCode()); 61 | sb.append(", mId=").append(mId); 62 | sb.append(", pId=").append(pId); 63 | sb.append("]"); 64 | return sb.toString(); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.builders.PathSelectors; 7 | import springfox.documentation.builders.RequestHandlerSelectors; 8 | import springfox.documentation.service.ApiInfo; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 12 | 13 | /** 14 | * swagger2配置 15 | * @author leeyom 16 | * @date 2017年10月19日 10:41 17 | */ 18 | // @Configuration 这里需要注意,如果项目架构是SSM,那就不要加这个注解,如果是 spring boot 架构类型的项目,就必须加上这个注解,让 spring 加载该配置。 19 | // spring boot 项目不需要添加此注解,SSM 项目需要加上此注解,否则将会报错。 20 | @EnableWebMvc 21 | @EnableSwagger2 22 | public class SwaggerConfig { 23 | @Bean 24 | public Docket buildDocket() { 25 | return new Docket(DocumentationType.SWAGGER_2) 26 | .apiInfo(buildApiInfo()) 27 | .select().apis(RequestHandlerSelectors.basePackage("com.artisan.handler")) 28 | .paths(PathSelectors.any()) 29 | .build(); 30 | } 31 | 32 | private ApiInfo buildApiInfo() { 33 | return new ApiInfoBuilder() 34 | .title("API接口文档") 35 | .build(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/UserRole.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "user_role") 6 | public class UserRole { 7 | /** 8 | * 用户id 9 | */ 10 | @Id 11 | @Column(name = "u_id") 12 | private Integer uId; 13 | 14 | /** 15 | * 角色id 16 | */ 17 | @Id 18 | @Column(name = "r_id") 19 | private Integer rId; 20 | 21 | /** 22 | * 获取用户id 23 | * 24 | * @return u_id - 用户id 25 | */ 26 | public Integer getuId() { 27 | return uId; 28 | } 29 | 30 | /** 31 | * 设置用户id 32 | * 33 | * @param uId 用户id 34 | */ 35 | public void setuId(Integer uId) { 36 | this.uId = uId; 37 | } 38 | 39 | /** 40 | * 获取角色id 41 | * 42 | * @return r_id - 角色id 43 | */ 44 | public Integer getrId() { 45 | return rId; 46 | } 47 | 48 | /** 49 | * 设置角色id 50 | * 51 | * @param rId 角色id 52 | */ 53 | public void setrId(Integer rId) { 54 | this.rId = rId; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | StringBuilder sb = new StringBuilder(); 60 | sb.append(getClass().getSimpleName()); 61 | sb.append(" ["); 62 | sb.append("Hash = ").append(hashCode()); 63 | sb.append(", uId=").append(uId); 64 | sb.append(", rId=").append(rId); 65 | sb.append("]"); 66 | return sb.toString(); 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/FilePermission.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "file_permission") 6 | public class FilePermission { 7 | /** 8 | * 文件主键id 9 | */ 10 | @Column(name = "f_id") 11 | private Integer fId; 12 | 13 | /** 14 | * 权限主键id 15 | */ 16 | @Column(name = "p_id") 17 | private Integer pId; 18 | 19 | /** 20 | * 获取文件主键id 21 | * 22 | * @return f_id - 文件主键id 23 | */ 24 | public Integer getfId() { 25 | return fId; 26 | } 27 | 28 | /** 29 | * 设置文件主键id 30 | * 31 | * @param fId 文件主键id 32 | */ 33 | public void setfId(Integer fId) { 34 | this.fId = fId; 35 | } 36 | 37 | /** 38 | * 获取权限主键id 39 | * 40 | * @return p_id - 权限主键id 41 | */ 42 | public Integer getpId() { 43 | return pId; 44 | } 45 | 46 | /** 47 | * 设置权限主键id 48 | * 49 | * @param pId 权限主键id 50 | */ 51 | public void setpId(Integer pId) { 52 | this.pId = pId; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | StringBuilder sb = new StringBuilder(); 58 | sb.append(getClass().getSimpleName()); 59 | sb.append(" ["); 60 | sb.append("Hash = ").append(hashCode()); 61 | sb.append(", fId=").append(fId); 62 | sb.append(", pId=").append(pId); 63 | sb.append("]"); 64 | return sb.toString(); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/RolePermission.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "role_permission") 6 | public class RolePermission { 7 | /** 8 | * 角色主键 9 | */ 10 | @Id 11 | @Column(name = "p_id") 12 | private Integer pId; 13 | 14 | /** 15 | * 权限主键 16 | */ 17 | @Id 18 | @Column(name = "r_id") 19 | private Integer rId; 20 | 21 | /** 22 | * 获取角色主键 23 | * 24 | * @return p_id - 角色主键 25 | */ 26 | public Integer getpId() { 27 | return pId; 28 | } 29 | 30 | /** 31 | * 设置角色主键 32 | * 33 | * @param pId 角色主键 34 | */ 35 | public void setpId(Integer pId) { 36 | this.pId = pId; 37 | } 38 | 39 | /** 40 | * 获取权限主键 41 | * 42 | * @return r_id - 权限主键 43 | */ 44 | public Integer getrId() { 45 | return rId; 46 | } 47 | 48 | /** 49 | * 设置权限主键 50 | * 51 | * @param rId 权限主键 52 | */ 53 | public void setrId(Integer rId) { 54 | this.rId = rId; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | StringBuilder sb = new StringBuilder(); 60 | sb.append(getClass().getSimpleName()); 61 | sb.append(" ["); 62 | sb.append("Hash = ").append(hashCode()); 63 | sb.append(", pId=").append(pId); 64 | sb.append(", rId=").append(rId); 65 | sb.append("]"); 66 | return sb.toString(); 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/PagePermission.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "page_permission") 6 | public class PagePermission { 7 | /** 8 | * 页面主键 9 | */ 10 | @Column(name = "page_id") 11 | private Integer pageId; 12 | 13 | /** 14 | * 权限主键 15 | */ 16 | @Column(name = "p_id") 17 | private Integer pId; 18 | 19 | /** 20 | * 获取页面主键 21 | * 22 | * @return page_id - 页面主键 23 | */ 24 | public Integer getPageId() { 25 | return pageId; 26 | } 27 | 28 | /** 29 | * 设置页面主键 30 | * 31 | * @param pageId 页面主键 32 | */ 33 | public void setPageId(Integer pageId) { 34 | this.pageId = pageId; 35 | } 36 | 37 | /** 38 | * 获取权限主键 39 | * 40 | * @return p_id - 权限主键 41 | */ 42 | public Integer getpId() { 43 | return pId; 44 | } 45 | 46 | /** 47 | * 设置权限主键 48 | * 49 | * @param pId 权限主键 50 | */ 51 | public void setpId(Integer pId) { 52 | this.pId = pId; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | StringBuilder sb = new StringBuilder(); 58 | sb.append(getClass().getSimpleName()); 59 | sb.append(" ["); 60 | sb.append("Hash = ").append(hashCode()); 61 | sb.append(", pageId=").append(pageId); 62 | sb.append(", pId=").append(pId); 63 | sb.append("]"); 64 | return sb.toString(); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/utils/Base64Util.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.utils; 2 | 3 | import org.apache.commons.codec.binary.Base64; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | 9 | /** 10 | * 将String进行base64编码解码,使用utf-8 11 | * @author Leeyom Wang 12 | * @date 2017年10月19日 11:52 13 | */ 14 | public class Base64Util { 15 | 16 | private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); 17 | 18 | private static final String UTF_8 = "UTF-8"; 19 | 20 | /** 21 | * 对给定的字符串进行base64解码操作 22 | */ 23 | public static String decodeData(String inputData) { 24 | try { 25 | if (null == inputData) { 26 | return null; 27 | } 28 | return new String(Base64.decodeBase64(inputData.getBytes(UTF_8)), UTF_8); 29 | } catch (UnsupportedEncodingException e) { 30 | logger.error(inputData, e); 31 | } 32 | 33 | return null; 34 | } 35 | 36 | /** 37 | * 对给定的字符串进行base64加密操作 38 | */ 39 | public static String encodeData(String inputData) { 40 | try { 41 | if (null == inputData) { 42 | return null; 43 | } 44 | return new String(Base64.encodeBase64(inputData.getBytes(UTF_8)), UTF_8); 45 | } catch (UnsupportedEncodingException e) { 46 | logger.error(inputData, e); 47 | } 48 | 49 | return null; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/Role.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | public class Role { 6 | /** 7 | * 主键 8 | */ 9 | @Id 10 | @Column(name = "r_id") 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer rId; 13 | 14 | /** 15 | * 角色名 16 | */ 17 | @Column(name = "role_name") 18 | private String roleName; 19 | 20 | /** 21 | * 获取主键 22 | * 23 | * @return r_id - 主键 24 | */ 25 | public Integer getrId() { 26 | return rId; 27 | } 28 | 29 | /** 30 | * 设置主键 31 | * 32 | * @param rId 主键 33 | */ 34 | public void setrId(Integer rId) { 35 | this.rId = rId; 36 | } 37 | 38 | /** 39 | * 获取角色名 40 | * 41 | * @return role_name - 角色名 42 | */ 43 | public String getRoleName() { 44 | return roleName; 45 | } 46 | 47 | /** 48 | * 设置角色名 49 | * 50 | * @param roleName 角色名 51 | */ 52 | public void setRoleName(String roleName) { 53 | this.roleName = roleName; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | StringBuilder sb = new StringBuilder(); 59 | sb.append(getClass().getSimpleName()); 60 | sb.append(" ["); 61 | sb.append("Hash = ").append(hashCode()); 62 | sb.append(", rId=").append(rId); 63 | sb.append(", roleName=").append(roleName); 64 | sb.append("]"); 65 | return sb.toString(); 66 | } 67 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/UserGroupRole.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "user_group_role") 6 | public class UserGroupRole { 7 | /** 8 | * 用户组 9 | */ 10 | @Id 11 | @Column(name = "group_id") 12 | private Integer groupId; 13 | 14 | /** 15 | * 角色 16 | */ 17 | @Id 18 | @Column(name = "r_id") 19 | private Integer rId; 20 | 21 | /** 22 | * 获取用户组 23 | * 24 | * @return group_id - 用户组 25 | */ 26 | public Integer getGroupId() { 27 | return groupId; 28 | } 29 | 30 | /** 31 | * 设置用户组 32 | * 33 | * @param groupId 用户组 34 | */ 35 | public void setGroupId(Integer groupId) { 36 | this.groupId = groupId; 37 | } 38 | 39 | /** 40 | * 获取角色 41 | * 42 | * @return r_id - 角色 43 | */ 44 | public Integer getrId() { 45 | return rId; 46 | } 47 | 48 | /** 49 | * 设置角色 50 | * 51 | * @param rId 角色 52 | */ 53 | public void setrId(Integer rId) { 54 | this.rId = rId; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | StringBuilder sb = new StringBuilder(); 60 | sb.append(getClass().getSimpleName()); 61 | sb.append(" ["); 62 | sb.append("Hash = ").append(hashCode()); 63 | sb.append(", groupId=").append(groupId); 64 | sb.append(", rId=").append(rId); 65 | sb.append("]"); 66 | return sb.toString(); 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/UserGroupUser.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "user_group_user") 6 | public class UserGroupUser { 7 | /** 8 | * 用户组 9 | */ 10 | @Id 11 | @Column(name = "group_id") 12 | private Integer groupId; 13 | 14 | /** 15 | * 用户 16 | 17 | */ 18 | @Id 19 | @Column(name = "u_id") 20 | private Integer uId; 21 | 22 | /** 23 | * 获取用户组 24 | * 25 | * @return group_id - 用户组 26 | */ 27 | public Integer getGroupId() { 28 | return groupId; 29 | } 30 | 31 | /** 32 | * 设置用户组 33 | * 34 | * @param groupId 用户组 35 | */ 36 | public void setGroupId(Integer groupId) { 37 | this.groupId = groupId; 38 | } 39 | 40 | /** 41 | * 获取用户 42 | 43 | * 44 | * @return u_id - 用户 45 | 46 | */ 47 | public Integer getuId() { 48 | return uId; 49 | } 50 | 51 | /** 52 | * 设置用户 53 | 54 | * 55 | * @param uId 用户 56 | 57 | */ 58 | public void setuId(Integer uId) { 59 | this.uId = uId; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | StringBuilder sb = new StringBuilder(); 65 | sb.append(getClass().getSimpleName()); 66 | sb.append(" ["); 67 | sb.append("Hash = ").append(hashCode()); 68 | sb.append(", groupId=").append(groupId); 69 | sb.append(", uId=").append(uId); 70 | sb.append("]"); 71 | return sb.toString(); 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/Permission.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | public class Permission { 6 | /** 7 | * 主键 8 | */ 9 | @Id 10 | @Column(name = "p_id") 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer pId; 13 | 14 | /** 15 | * 权限类型 16 | */ 17 | @Column(name = "p_type_name") 18 | private String pTypeName; 19 | 20 | /** 21 | * 获取主键 22 | * 23 | * @return p_id - 主键 24 | */ 25 | public Integer getpId() { 26 | return pId; 27 | } 28 | 29 | /** 30 | * 设置主键 31 | * 32 | * @param pId 主键 33 | */ 34 | public void setpId(Integer pId) { 35 | this.pId = pId; 36 | } 37 | 38 | /** 39 | * 获取权限类型 40 | * 41 | * @return p_type_name - 权限类型 42 | */ 43 | public String getpTypeName() { 44 | return pTypeName; 45 | } 46 | 47 | /** 48 | * 设置权限类型 49 | * 50 | * @param pTypeName 权限类型 51 | */ 52 | public void setpTypeName(String pTypeName) { 53 | this.pTypeName = pTypeName; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | StringBuilder sb = new StringBuilder(); 59 | sb.append(getClass().getSimpleName()); 60 | sb.append(" ["); 61 | sb.append("Hash = ").append(hashCode()); 62 | sb.append(", pId=").append(pId); 63 | sb.append(", pTypeName=").append(pTypeName); 64 | sb.append("]"); 65 | return sb.toString(); 66 | } 67 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/Page.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | public class Page { 6 | /** 7 | * 主键 8 | */ 9 | @Id 10 | @Column(name = "page_id") 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer pageId; 13 | 14 | /** 15 | * 页面元素编码 16 | */ 17 | @Column(name = "page_code") 18 | private String pageCode; 19 | 20 | /** 21 | * 获取主键 22 | * 23 | * @return page_id - 主键 24 | */ 25 | public Integer getPageId() { 26 | return pageId; 27 | } 28 | 29 | /** 30 | * 设置主键 31 | * 32 | * @param pageId 主键 33 | */ 34 | public void setPageId(Integer pageId) { 35 | this.pageId = pageId; 36 | } 37 | 38 | /** 39 | * 获取页面元素编码 40 | * 41 | * @return page_code - 页面元素编码 42 | */ 43 | public String getPageCode() { 44 | return pageCode; 45 | } 46 | 47 | /** 48 | * 设置页面元素编码 49 | * 50 | * @param pageCode 页面元素编码 51 | */ 52 | public void setPageCode(String pageCode) { 53 | this.pageCode = pageCode; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | StringBuilder sb = new StringBuilder(); 59 | sb.append(getClass().getSimpleName()); 60 | sb.append(" ["); 61 | sb.append("Hash = ").append(hashCode()); 62 | sb.append(", pageId=").append(pageId); 63 | sb.append(", pageCode=").append(pageCode); 64 | sb.append("]"); 65 | return sb.toString(); 66 | } 67 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/utils/VerificationUtil.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.utils; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | /** 7 | * 验证工具类 8 | * @author Leeyom Wang 9 | * @date 2017年10月19日 11:53 10 | */ 11 | public class VerificationUtil { 12 | /** 13 | * 邮箱格式验证 14 | * @param email 15 | * @return 16 | */ 17 | public static boolean isEmail(String email) { 18 | String str = "^([a-zA-Z0-9_.\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"; 19 | Pattern p = Pattern.compile(str); 20 | Matcher m = p.matcher(email); 21 | return m.matches(); 22 | } 23 | 24 | /*** 25 | * 密码验证 26 | * 27 | */ 28 | public static boolean isPassword(String password) { 29 | String str = "^([a-zA-Z0-9]{0,50})"; 30 | Pattern p = Pattern.compile(str); 31 | Matcher m = p.matcher(password); 32 | return m.matches(); 33 | } 34 | 35 | /*** 36 | * 用户名验证证 37 | */ 38 | public static boolean isAdminname(String adminname) { 39 | String str = "^([a-zA-Z]{1}[a-zA-Z0-9_]{5,15})"; 40 | Pattern p = Pattern.compile(str); 41 | Matcher m = p.matcher(adminname); 42 | return m.matches(); 43 | } 44 | 45 | public static boolean isImage(String ContentType) { 46 | String str = "^(image/gif|image/jpg|image/png|image/jpeg)$"; 47 | Pattern p = Pattern.compile(str); 48 | Matcher m = p.matcher(ContentType); 49 | return m.matches(); 50 | } 51 | 52 | /** 53 | * 判断字符串是否为数字 54 | * @param str 55 | * @return 56 | */ 57 | public static boolean isNumeric(String str) { 58 | Pattern pattern = Pattern.compile("[0-9]*"); 59 | Matcher isNum = pattern.matcher(str); 60 | if (!isNum.matches()) { 61 | return false; 62 | } 63 | return true; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/File.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | public class File { 6 | /** 7 | * 主键 8 | */ 9 | @Id 10 | @Column(name = "f_id") 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer fId; 13 | 14 | /** 15 | * 文件名 16 | */ 17 | @Column(name = "file_name") 18 | private String fileName; 19 | 20 | /** 21 | * 文件路径 22 | */ 23 | @Column(name = "file_url") 24 | private String fileUrl; 25 | 26 | /** 27 | * 获取主键 28 | * 29 | * @return f_id - 主键 30 | */ 31 | public Integer getfId() { 32 | return fId; 33 | } 34 | 35 | /** 36 | * 设置主键 37 | * 38 | * @param fId 主键 39 | */ 40 | public void setfId(Integer fId) { 41 | this.fId = fId; 42 | } 43 | 44 | /** 45 | * 获取文件名 46 | * 47 | * @return file_name - 文件名 48 | */ 49 | public String getFileName() { 50 | return fileName; 51 | } 52 | 53 | /** 54 | * 设置文件名 55 | * 56 | * @param fileName 文件名 57 | */ 58 | public void setFileName(String fileName) { 59 | this.fileName = fileName; 60 | } 61 | 62 | /** 63 | * 获取文件路径 64 | * 65 | * @return file_url - 文件路径 66 | */ 67 | public String getFileUrl() { 68 | return fileUrl; 69 | } 70 | 71 | /** 72 | * 设置文件路径 73 | * 74 | * @param fileUrl 文件路径 75 | */ 76 | public void setFileUrl(String fileUrl) { 77 | this.fileUrl = fileUrl; 78 | } 79 | 80 | @Override 81 | public String toString() { 82 | StringBuilder sb = new StringBuilder(); 83 | sb.append(getClass().getSimpleName()); 84 | sb.append(" ["); 85 | sb.append("Hash = ").append(hashCode()); 86 | sb.append(", fId=").append(fId); 87 | sb.append(", fileName=").append(fileName); 88 | sb.append(", fileUrl=").append(fileUrl); 89 | sb.append("]"); 90 | return sb.toString(); 91 | } 92 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/vo/UserVO.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.vo; 2 | 3 | 4 | import java.util.Date; 5 | 6 | /** 7 | * User视图层实体类对象 8 | * @author leeyom 9 | * @date 2017年10月30日 21:15 10 | */ 11 | public class UserVO { 12 | 13 | /** 14 | * 主键 15 | */ 16 | private Integer uId; 17 | 18 | /** 19 | * 用户名 20 | */ 21 | private String uName; 22 | 23 | /** 24 | * 生日 25 | */ 26 | private Date birthday; 27 | 28 | /** 29 | * 性别 30 | */ 31 | private Integer sex; 32 | 33 | /** 34 | * 年龄 35 | */ 36 | private Integer age; 37 | 38 | /** 39 | * token 40 | */ 41 | private String token; 42 | 43 | public Integer getuId() { 44 | return uId; 45 | } 46 | 47 | public void setuId(Integer uId) { 48 | this.uId = uId; 49 | } 50 | 51 | public String getuName() { 52 | return uName; 53 | } 54 | 55 | public void setuName(String uName) { 56 | this.uName = uName; 57 | } 58 | 59 | public Date getBirthday() { 60 | return birthday; 61 | } 62 | 63 | public void setBirthday(Date birthday) { 64 | this.birthday = birthday; 65 | } 66 | 67 | public Integer getSex() { 68 | return sex; 69 | } 70 | 71 | public void setSex(Integer sex) { 72 | this.sex = sex; 73 | } 74 | 75 | public Integer getAge() { 76 | return age; 77 | } 78 | 79 | public void setAge(Integer age) { 80 | this.age = age; 81 | } 82 | 83 | public String getToken() { 84 | return token; 85 | } 86 | 87 | public void setToken(String token) { 88 | this.token = token; 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | return "UserVO{" + 94 | "uId=" + uId + 95 | ", uName='" + uName + '\'' + 96 | ", birthday=" + birthday + 97 | ", sex=" + sex + 98 | ", age=" + age + 99 | ", token='" + token + '\'' + 100 | '}'; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/utils/JsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.utils; 2 | 3 | import com.google.gson.stream.JsonReader; 4 | import net.sf.json.JSONObject; 5 | 6 | import java.io.IOException; 7 | import java.io.StringReader; 8 | import java.util.*; 9 | 10 | /** 11 | * json处理工具类 12 | * @author Leeyom Wang 13 | * @date 2017年10月19日 12:05 14 | */ 15 | public class JsonUtils { 16 | 17 | /** 18 | * 解析json字符串 19 | * @param json json字符串:{"name":"jack","age":12} 20 | * @return 转换后的map键值对 21 | */ 22 | public static Map toParam(String json) { 23 | Map map = new HashMap(); 24 | JsonReader reader = new JsonReader(new StringReader(json)); 25 | reader.setLenient(true); // 在宽松模式下解析 26 | try { 27 | reader.beginObject(); // 开始解析一个新的对象 28 | while (reader.hasNext()) { 29 | String key = reader.nextName(); 30 | String value = reader.nextString(); 31 | map.put(key, value); 32 | } 33 | reader.endObject(); // 结束对象的解析 34 | } catch (IOException e) { 35 | e.printStackTrace(); 36 | } 37 | return map; 38 | } 39 | 40 | /** 41 | * json拼串操作 42 | * @param list 集合 43 | * @param count 44 | * @return 45 | */ 46 | public static String list2Json(List list, int count) { 47 | Map map = new HashMap(); 48 | map.put("rows", list); 49 | map.put("total", count); 50 | JSONObject jsonObject = JSONObject.fromObject(map); 51 | return jsonObject.toString(); 52 | } 53 | 54 | /** 55 | * 按逗号截取字符串获取整型参数 56 | * @param string 需要截取的字符串 57 | * @return 整形数组 58 | */ 59 | public static List strToList(String string) { 60 | String[] split = string.split(","); 61 | for (int i = 0; i < split.length; i++) { 62 | split[i] = split[i].trim(); 63 | } 64 | List asList = Arrays.asList(split); 65 | List list = new ArrayList(); 66 | for (int i = 0; i < asList.size(); i++) { 67 | list.add(Integer.parseInt(asList.get(i))); 68 | } 69 | return list; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/UserGroup.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | @Table(name = "user_group") 6 | public class UserGroup { 7 | /** 8 | * 主键 9 | */ 10 | @Id 11 | @Column(name = "group_id") 12 | @GeneratedValue(strategy = GenerationType.IDENTITY) 13 | private Integer groupId; 14 | 15 | /** 16 | * 用户组名称 17 | */ 18 | @Column(name = "group_name") 19 | private String groupName; 20 | 21 | /** 22 | * 父级用户组名称 23 | */ 24 | @Column(name = "parent_group_name") 25 | private String parentGroupName; 26 | 27 | /** 28 | * 获取主键 29 | * 30 | * @return group_id - 主键 31 | */ 32 | public Integer getGroupId() { 33 | return groupId; 34 | } 35 | 36 | /** 37 | * 设置主键 38 | * 39 | * @param groupId 主键 40 | */ 41 | public void setGroupId(Integer groupId) { 42 | this.groupId = groupId; 43 | } 44 | 45 | /** 46 | * 获取用户组名称 47 | * 48 | * @return group_name - 用户组名称 49 | */ 50 | public String getGroupName() { 51 | return groupName; 52 | } 53 | 54 | /** 55 | * 设置用户组名称 56 | * 57 | * @param groupName 用户组名称 58 | */ 59 | public void setGroupName(String groupName) { 60 | this.groupName = groupName; 61 | } 62 | 63 | /** 64 | * 获取父级用户组名称 65 | * 66 | * @return parent_group_name - 父级用户组名称 67 | */ 68 | public String getParentGroupName() { 69 | return parentGroupName; 70 | } 71 | 72 | /** 73 | * 设置父级用户组名称 74 | * 75 | * @param parentGroupName 父级用户组名称 76 | */ 77 | public void setParentGroupName(String parentGroupName) { 78 | this.parentGroupName = parentGroupName; 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | StringBuilder sb = new StringBuilder(); 84 | sb.append(getClass().getSimpleName()); 85 | sb.append(" ["); 86 | sb.append("Hash = ").append(hashCode()); 87 | sb.append(", groupId=").append(groupId); 88 | sb.append(", groupName=").append(groupName); 89 | sb.append(", parentGroupName=").append(parentGroupName); 90 | sb.append("]"); 91 | return sb.toString(); 92 | } 93 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/authorization/manager/impl/JsonWebTokenManagerImpl.java: -------------------------------------------------------------------------------- 1 | package com.artisan.authorization.manager.impl; 2 | 3 | import com.artisan.authorization.manager.JsonWebTokenManager; 4 | import com.artisan.common.constant.Constants; 5 | import com.artisan.common.utils.StringUtils; 6 | import io.jsonwebtoken.*; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Calendar; 10 | import java.util.Date; 11 | import java.util.UUID; 12 | 13 | @Component 14 | public class JsonWebTokenManagerImpl implements JsonWebTokenManager { 15 | 16 | 17 | @Override 18 | public String createToken(long userId) { 19 | 20 | // JWT的有效期为两个小时 21 | Calendar ca = Calendar.getInstance(); 22 | ca.setTime(new Date()); 23 | ca.add(Calendar.HOUR_OF_DAY, 2); 24 | 25 | // 签发 token 26 | String token = Jwts.builder() 27 | // JWT 的签发者 28 | .setIssuer("leeyom.com") 29 | // 主题 30 | .setSubject("Test JWT") 31 | // JWT 的接收方 32 | .setAudience("client.leeyom.com") 33 | // 过期时间 34 | .setExpiration(ca.getTime()) 35 | // JWT 的签发时间 36 | .setIssuedAt(new Date()) 37 | // 载荷中自定义数据 38 | .claim("userId", userId + "") 39 | // JWT的唯一标识 40 | .setId(UUID.randomUUID().toString()) 41 | // 签名 42 | .signWith(SignatureAlgorithm.HS256, Constants.SECRET_KEY) 43 | .compact(); 44 | return token; 45 | } 46 | 47 | @Override 48 | public boolean checkToken(String token) { 49 | try { 50 | // 解析 JWT 字符串中的数据,并进行最基础的验证(可选),比如接收方是否是我,userId 不能为 null 等等 51 | Claims claims = Jwts.parser() 52 | .setSigningKey(Constants.SECRET_KEY) 53 | .parseClaimsJws(token) 54 | .getBody(); 55 | String userId = claims.get("userId", String.class); 56 | return StringUtils.notNull(userId); 57 | 58 | } catch (SignatureException | ExpiredJwtException e) { 59 | // 如果密钥不正确,将会解析失败,抛出 SignatureException 异常,说明该 JWT 字符串是伪造的 60 | // 如果‘过期时间字段’已经早于当前时间,将会抛出 ExpiredJwtException 异常,说明本次请求已经失效 61 | return false; 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/Menu.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | public class Menu { 6 | /** 7 | * 主键 8 | */ 9 | @Id 10 | @Column(name = "m_id") 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer mId; 13 | 14 | /** 15 | * 菜单名称 16 | */ 17 | @Column(name = "menu_name") 18 | private String menuName; 19 | 20 | /** 21 | * 菜单URL 22 | */ 23 | @Column(name = "menu_url") 24 | private String menuUrl; 25 | 26 | /** 27 | * 父级菜单 28 | */ 29 | @Column(name = "parent_m_id") 30 | private Integer parentMId; 31 | 32 | /** 33 | * 获取主键 34 | * 35 | * @return m_id - 主键 36 | */ 37 | public Integer getmId() { 38 | return mId; 39 | } 40 | 41 | /** 42 | * 设置主键 43 | * 44 | * @param mId 主键 45 | */ 46 | public void setmId(Integer mId) { 47 | this.mId = mId; 48 | } 49 | 50 | /** 51 | * 获取菜单名称 52 | * 53 | * @return menu_name - 菜单名称 54 | */ 55 | public String getMenuName() { 56 | return menuName; 57 | } 58 | 59 | /** 60 | * 设置菜单名称 61 | * 62 | * @param menuName 菜单名称 63 | */ 64 | public void setMenuName(String menuName) { 65 | this.menuName = menuName; 66 | } 67 | 68 | /** 69 | * 获取菜单URL 70 | * 71 | * @return menu_url - 菜单URL 72 | */ 73 | public String getMenuUrl() { 74 | return menuUrl; 75 | } 76 | 77 | /** 78 | * 设置菜单URL 79 | * 80 | * @param menuUrl 菜单URL 81 | */ 82 | public void setMenuUrl(String menuUrl) { 83 | this.menuUrl = menuUrl; 84 | } 85 | 86 | /** 87 | * 获取父级菜单 88 | * 89 | * @return parent_m_id - 父级菜单 90 | */ 91 | public Integer getParentMId() { 92 | return parentMId; 93 | } 94 | 95 | /** 96 | * 设置父级菜单 97 | * 98 | * @param parentMId 父级菜单 99 | */ 100 | public void setParentMId(Integer parentMId) { 101 | this.parentMId = parentMId; 102 | } 103 | 104 | @Override 105 | public String toString() { 106 | StringBuilder sb = new StringBuilder(); 107 | sb.append(getClass().getSimpleName()); 108 | sb.append(" ["); 109 | sb.append("Hash = ").append(hashCode()); 110 | sb.append(", mId=").append(mId); 111 | sb.append(", menuName=").append(menuName); 112 | sb.append(", menuUrl=").append(menuUrl); 113 | sb.append(", parentMId=").append(parentMId); 114 | sb.append("]"); 115 | return sb.toString(); 116 | } 117 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/filter/CorsFilter.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.filter; 2 | 3 | import com.github.pagehelper.StringUtil; 4 | import org.apache.log4j.Logger; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.servlet.*; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | 11 | /** 12 | * 处理跨域的过滤器 13 | * @author Leeyom Wang 14 | * @date 2017年10月19日 14:47 15 | */ 16 | @Component 17 | public class CorsFilter implements Filter { 18 | 19 | private static final Logger LOGGER = Logger.getLogger(CorsFilter.class); 20 | 21 | private String allowOrigin; 22 | private String allowMethods; 23 | private String allowCredentials; 24 | private String allowHeaders; 25 | private String exposeHeaders; 26 | 27 | @Override 28 | public void init(FilterConfig filterConfig) throws ServletException { 29 | allowOrigin = filterConfig.getInitParameter("allowOrigin"); 30 | allowMethods = filterConfig.getInitParameter("allowMethods"); 31 | allowCredentials = filterConfig.getInitParameter("allowCredentials"); 32 | allowHeaders = filterConfig.getInitParameter("allowHeaders"); 33 | exposeHeaders = filterConfig.getInitParameter("exposeHeaders"); 34 | } 35 | 36 | /** 37 | * 通过CORS技术实现AJAX跨域访问, 只要将CORS响应头写入response对象中即可 38 | * @param req 39 | * @param res 40 | * @param chain 41 | * @throws IOException 42 | * @throws ServletException 43 | */ 44 | @Override 45 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 46 | HttpServletResponse response = (HttpServletResponse) res; 47 | if (StringUtil.isNotEmpty(allowOrigin)) { 48 | //允许访问的客户端域名,例如:http://web.xxx.com,若为*,则表示从任意域都能访问,即不做任何限制; 49 | response.setHeader("Access-Control-Allow-Origin", allowOrigin); 50 | } 51 | if (StringUtil.isNotEmpty(allowMethods)) { 52 | //允许访问的请求方式,多个用逗号分割,例如:GET,POST,PUT,DELETE,OPTIONS; 53 | response.setHeader("Access-Control-Allow-Methods", allowMethods); 54 | } 55 | if (StringUtil.isNotEmpty(allowCredentials)) { 56 | //是否允许请求带有验证信息,若要获取客户端域下的cookie时,需要将其设置为true; 57 | response.setHeader("Access-Control-Allow-Credentials", allowCredentials); 58 | } 59 | if (StringUtil.isNotEmpty(allowHeaders)) { 60 | //允许服务端访问的客户端请求头,多个请求头用逗号分割,例如:Content-Type,Access-Token,timestamp 61 | response.setHeader("Access-Control-Allow-Headers", allowHeaders); 62 | } 63 | if (StringUtil.isNotEmpty(exposeHeaders)) { 64 | //允许客户端访问的服务端响应头,多个响应头用逗号分割。 65 | response.setHeader("Access-Control-Expose-Headers", exposeHeaders); 66 | } 67 | chain.doFilter(req, res); 68 | } 69 | 70 | @Override 71 | public void destroy() { 72 | 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/resources/spring/spring-mvc.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/Operation.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import javax.persistence.*; 4 | 5 | public class Operation { 6 | /** 7 | * 主键 8 | */ 9 | @Id 10 | @Column(name = "o_id") 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private Integer oId; 13 | 14 | /** 15 | * 操作名称 16 | */ 17 | @Column(name = "o_name") 18 | private String oName; 19 | 20 | /** 21 | * 操作编码 22 | */ 23 | @Column(name = "o_code") 24 | private String oCode; 25 | 26 | /** 27 | * 拦截的url 28 | */ 29 | private String url; 30 | 31 | /** 32 | * 父级操作id 33 | */ 34 | @Column(name = "parent_id") 35 | private String parentId; 36 | 37 | /** 38 | * 获取主键 39 | * 40 | * @return o_id - 主键 41 | */ 42 | public Integer getoId() { 43 | return oId; 44 | } 45 | 46 | /** 47 | * 设置主键 48 | * 49 | * @param oId 主键 50 | */ 51 | public void setoId(Integer oId) { 52 | this.oId = oId; 53 | } 54 | 55 | /** 56 | * 获取操作名称 57 | * 58 | * @return o_name - 操作名称 59 | */ 60 | public String getoName() { 61 | return oName; 62 | } 63 | 64 | /** 65 | * 设置操作名称 66 | * 67 | * @param oName 操作名称 68 | */ 69 | public void setoName(String oName) { 70 | this.oName = oName; 71 | } 72 | 73 | /** 74 | * 获取操作编码 75 | * 76 | * @return o_code - 操作编码 77 | */ 78 | public String getoCode() { 79 | return oCode; 80 | } 81 | 82 | /** 83 | * 设置操作编码 84 | * 85 | * @param oCode 操作编码 86 | */ 87 | public void setoCode(String oCode) { 88 | this.oCode = oCode; 89 | } 90 | 91 | /** 92 | * 获取拦截的url 93 | * 94 | * @return url - 拦截的url 95 | */ 96 | public String getUrl() { 97 | return url; 98 | } 99 | 100 | /** 101 | * 设置拦截的url 102 | * 103 | * @param url 拦截的url 104 | */ 105 | public void setUrl(String url) { 106 | this.url = url; 107 | } 108 | 109 | /** 110 | * 获取父级操作id 111 | * 112 | * @return parent_id - 父级操作id 113 | */ 114 | public String getParentId() { 115 | return parentId; 116 | } 117 | 118 | /** 119 | * 设置父级操作id 120 | * 121 | * @param parentId 父级操作id 122 | */ 123 | public void setParentId(String parentId) { 124 | this.parentId = parentId; 125 | } 126 | 127 | @Override 128 | public String toString() { 129 | StringBuilder sb = new StringBuilder(); 130 | sb.append(getClass().getSimpleName()); 131 | sb.append(" ["); 132 | sb.append("Hash = ").append(hashCode()); 133 | sb.append(", oId=").append(oId); 134 | sb.append(", oName=").append(oName); 135 | sb.append(", oCode=").append(oCode); 136 | sb.append(", url=").append(url); 137 | sb.append(", parentId=").append(parentId); 138 | sb.append("]"); 139 | return sb.toString(); 140 | } 141 | } -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/aspect/SecurityAspect.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.aspect; 2 | 3 | import com.artisan.authorization.manager.TokenManager; 4 | import com.artisan.authorization.model.TokenModel; 5 | import com.artisan.common.annotation.IgnoreSecurity; 6 | import com.artisan.common.constant.Constants; 7 | import com.artisan.common.exception.TokenException; 8 | import com.artisan.common.utils.Base64Util; 9 | import com.artisan.common.utils.WebContextUtil; 10 | import org.apache.log4j.Logger; 11 | import org.aspectj.lang.ProceedingJoinPoint; 12 | import org.aspectj.lang.annotation.Around; 13 | import org.aspectj.lang.annotation.Aspect; 14 | import org.aspectj.lang.reflect.MethodSignature; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Component; 17 | 18 | import javax.servlet.http.HttpServletRequest; 19 | import java.lang.reflect.Method; 20 | import java.net.URL; 21 | import java.text.SimpleDateFormat; 22 | 23 | 24 | /** 25 | * token有效性判断切面 26 | * @author leeyom 27 | * @date 2017年10月19日 10:41 28 | */ 29 | @Component 30 | @Aspect 31 | public class SecurityAspect { 32 | 33 | private static final Logger LOGGER = Logger.getLogger(SecurityAspect.class); 34 | 35 | @Autowired 36 | TokenManager tokenManager; 37 | 38 | @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)") 39 | public Object execute(ProceedingJoinPoint pjp) throws Throwable { 40 | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); 41 | 42 | // 从切点上获取目标方法 43 | MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); 44 | Method method = methodSignature.getMethod(); 45 | 46 | // *******************************放行swagger相关的请求url,开发阶段打开,生产环境注释掉******************************* 47 | 48 | HttpServletRequest request = WebContextUtil.getRequest(); 49 | URL requestUrl = new URL(request.getRequestURL().toString()); 50 | if (requestUrl.getPath().contains("configuration")) { 51 | return pjp.proceed(); 52 | } 53 | if (requestUrl.getPath().contains("swagger")) { 54 | return pjp.proceed(); 55 | } 56 | if (requestUrl.getPath().contains("api")) { 57 | return pjp.proceed(); 58 | } 59 | // ************************************************************************************************************ 60 | 61 | // 若目标方法忽略了安全性检查,则直接调用目标方法 62 | if (method.isAnnotationPresent(IgnoreSecurity.class)) { 63 | return pjp.proceed(); 64 | } 65 | 66 | // 从 request header 中获取当前 token 67 | String authentication = request.getHeader(Constants.DEFAULT_TOKEN_NAME); 68 | TokenModel tokenModel = tokenManager.getToken(Base64Util.decodeData(authentication)); 69 | 70 | 71 | // 检查 token 有效性(检查是否登录) 72 | if (!tokenManager.checkToken(tokenModel)) { 73 | String message = "token " + Base64Util.decodeData(authentication) + " is invalid!!!"; 74 | LOGGER.debug("message : " + message); 75 | throw new TokenException(message); 76 | } 77 | 78 | // 调用目标方法 79 | return pjp.proceed(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/authorization/manager/impl/RedisTokenManager.java: -------------------------------------------------------------------------------- 1 | package com.artisan.authorization.manager.impl; 2 | 3 | import com.artisan.authorization.manager.TokenManager; 4 | import com.artisan.authorization.model.TokenModel; 5 | import com.artisan.common.constant.Constants; 6 | import com.artisan.common.utils.Base64Util; 7 | import com.artisan.common.utils.StringUtils; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.redis.core.RedisTemplate; 10 | import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.text.SimpleDateFormat; 14 | import java.util.Date; 15 | import java.util.UUID; 16 | import java.util.concurrent.TimeUnit; 17 | 18 | /** 19 | * 通过Redis存储和验证token的实现类 20 | * @author leeyom 21 | * @date 2017年10月19日 10:41 22 | * @see com.artisan.authorization.manager.TokenManager 23 | */ 24 | @Component 25 | public class RedisTokenManager implements TokenManager { 26 | 27 | private RedisTemplate redis; 28 | private final SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMddHHmmss"); 29 | 30 | @Autowired 31 | public void setRedis(RedisTemplate redis) { 32 | this.redis = redis; 33 | //泛型设置成Long后必须更改对应的序列化方案 34 | redis.setKeySerializer(new JdkSerializationRedisSerializer()); 35 | } 36 | 37 | @Override 38 | public TokenModel createToken(long userId) { 39 | //uuid 40 | String uuid = UUID.randomUUID().toString().replace("-", ""); 41 | //时间戳 42 | String timestamp = SDF.format(new Date()); 43 | //token => userId_timestamp_uuid; 44 | String token = userId + "_" + timestamp + "_" + uuid; 45 | TokenModel model = new TokenModel(userId, uuid, timestamp); 46 | //存储到redis并设置过期时间(有效期为2个小时) 47 | redis.boundValueOps(userId).set(Base64Util.encodeData(token), Constants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS); 48 | return model; 49 | } 50 | 51 | @Override 52 | public TokenModel getToken(String authentication) { 53 | if (authentication == null || authentication.length() == 0) { 54 | return null; 55 | } 56 | String[] param = authentication.split("_"); 57 | if (param.length != 3) { 58 | return null; 59 | } 60 | //使用userId和源token简单拼接成的token,可以增加加密措施 61 | long userId = Long.parseLong(param[0]); 62 | String timestamp = param[1]; 63 | String uuid = param[2]; 64 | return new TokenModel(userId, uuid, timestamp); 65 | } 66 | 67 | @Override 68 | public boolean checkToken(TokenModel model) { 69 | if (model == null) { 70 | return false; 71 | } 72 | String token = redis.boundValueOps(model.getUserId()).get(); 73 | if (token == null || !(Base64Util.decodeData(token)).equals(model.getToken())) { 74 | return false; 75 | } 76 | //如果验证成功,说明此用户进行了一次有效操作,延长token的过期时间(2个小时) 77 | redis.boundValueOps(model.getUserId()).expire(Constants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS); 78 | return true; 79 | } 80 | 81 | @Override 82 | public void deleteToken(long userId) { 83 | if (redis.hasKey(userId)) { 84 | redis.delete(userId); 85 | } 86 | } 87 | 88 | @Override 89 | public boolean hasToken(long userId) { 90 | String token = redis.boundValueOps(userId).get(); 91 | return StringUtils.notNull(token); 92 | } 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/resources/generator/generatorConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 |
37 | 38 | 39 |
40 | 41 | 42 |
43 | 44 | 45 |
46 | 47 | 48 |
49 | 50 | 51 |
52 | 53 | 54 |
55 | 56 | 57 |
58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/pojo/db/User.java: -------------------------------------------------------------------------------- 1 | package com.artisan.pojo.db; 2 | 3 | import org.hibernate.validator.constraints.Length; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import javax.validation.constraints.Max; 10 | import javax.validation.constraints.Min; 11 | import javax.validation.constraints.NotEmpty; 12 | import java.util.Date; 13 | 14 | public class User { 15 | /** 16 | * 主键 17 | */ 18 | @Id 19 | @Column(name = "u_id") 20 | @GeneratedValue(strategy = GenerationType.IDENTITY) 21 | private Integer uId; 22 | 23 | /** 24 | * 用户名 25 | */ 26 | @Column(name = "user_name") 27 | @NotEmpty(message = "姓名不能为空") 28 | private String userName; 29 | 30 | /** 31 | * 密码 32 | */ 33 | @NotEmpty(message = "密码不能为空") 34 | @Length(min = 6, message = "密码长度不能小于 6 位") 35 | private String password; 36 | 37 | /** 38 | * 生日 39 | */ 40 | private Date birthday; 41 | 42 | /** 43 | * 性别 44 | */ 45 | private Integer sex; 46 | 47 | /** 48 | * 年龄 49 | */ 50 | @Max(value = 100, message = "年龄不能大于 100 岁") 51 | @Min(value = 18, message = "必须年满 18 岁!") 52 | private Integer age; 53 | 54 | /** 55 | * 获取主键 56 | * @return u_id - 主键 57 | */ 58 | public Integer getuId() { 59 | return uId; 60 | } 61 | 62 | /** 63 | * 设置主键 64 | * @param uId 主键 65 | */ 66 | public void setuId(Integer uId) { 67 | this.uId = uId; 68 | } 69 | 70 | /** 71 | * 获取用户名 72 | * @return user_name - 用户名 73 | */ 74 | public String getUserName() { 75 | return userName; 76 | } 77 | 78 | /** 79 | * 设置用户名 80 | * @param userName 用户名 81 | */ 82 | public void setUserName(String userName) { 83 | this.userName = userName; 84 | } 85 | 86 | /** 87 | * 获取密码 88 | * @return password - 密码 89 | */ 90 | public String getPassword() { 91 | return password; 92 | } 93 | 94 | /** 95 | * 设置密码 96 | * @param password 密码 97 | */ 98 | public void setPassword(String password) { 99 | this.password = password; 100 | } 101 | 102 | /** 103 | * 获取生日 104 | * @return birthday - 生日 105 | */ 106 | public Date getBirthday() { 107 | return birthday; 108 | } 109 | 110 | /** 111 | * 设置生日 112 | * @param birthday 生日 113 | */ 114 | public void setBirthday(Date birthday) { 115 | this.birthday = birthday; 116 | } 117 | 118 | /** 119 | * 获取性别 120 | * @return sex - 性别 121 | */ 122 | public Integer getSex() { 123 | return sex; 124 | } 125 | 126 | /** 127 | * 设置性别 128 | * @param sex 性别 129 | */ 130 | public void setSex(Integer sex) { 131 | this.sex = sex; 132 | } 133 | 134 | /** 135 | * 获取年龄 136 | * @return age - 年龄 137 | */ 138 | public Integer getAge() { 139 | return age; 140 | } 141 | 142 | /** 143 | * 设置年龄 144 | * @param age 年龄 145 | */ 146 | public void setAge(Integer age) { 147 | this.age = age; 148 | } 149 | 150 | @Override 151 | public String toString() { 152 | StringBuilder sb = new StringBuilder(); 153 | sb.append(getClass().getSimpleName()); 154 | sb.append(" ["); 155 | sb.append("Hash = ").append(hashCode()); 156 | sb.append(", uId=").append(uId); 157 | sb.append(", userName=").append(userName); 158 | sb.append(", password=").append(password); 159 | sb.append(", birthday=").append(birthday); 160 | sb.append(", sex=").append(sex); 161 | sb.append(", age=").append(age); 162 | sb.append("]"); 163 | return sb.toString(); 164 | } 165 | } -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | code-artisan 7 | 8 | 9 | contextConfigLocation 10 | classpath:spring/applicationContext.xml 11 | 12 | 13 | 14 | 15 | org.springframework.web.context.ContextLoaderListener 16 | 17 | 18 | 19 | 20 | org.springframework.web.util.IntrospectorCleanupListener 21 | 22 | 23 | 24 | 25 | SpringMVC 26 | org.springframework.web.servlet.DispatcherServlet 27 | 28 | contextConfigLocation 29 | classpath:spring/spring-mvc.xml 30 | 31 | 1 32 | true 33 | 34 | 35 | 36 | SpringMVC 37 | / 38 | 39 | 40 | 41 | 42 | encodingFilter 43 | org.springframework.web.filter.CharacterEncodingFilter 44 | true 45 | 46 | encoding 47 | UTF-8 48 | 49 | 50 | 51 | encodingFilter 52 | /* 53 | 54 | 55 | 56 | 57 | corsFilter 58 | com.artisan.common.filter.CorsFilter 59 | 60 | allowOrigin 61 | * 62 | 63 | 64 | allowMethods 65 | GET,POST,PUT,DELETE,OPTIONS 66 | 67 | 68 | allowCredentials 69 | true 70 | 71 | 72 | allowHeaders 73 | Content-Type,Access-Token 74 | 75 | 76 | 77 | 78 | corsFilter 79 | /* 80 | 81 | 82 | 83 | 84 | DruidStatView 85 | com.alibaba.druid.support.http.StatViewServlet 86 | 87 | 88 | resetEnable 89 | true 90 | 91 | 92 | 93 | loginUsername 94 | root 95 | 96 | 97 | 98 | loginPassword 99 | root 100 | 101 | 102 | 103 | DruidStatView 104 | /druid/* 105 | 106 | 107 | 108 | /index.jsp 109 | 110 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/aspect/ExceptionAspect.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.aspect; 2 | 3 | import com.artisan.common.exception.TokenException; 4 | import com.artisan.pojo.vo.ResultBean; 5 | import org.apache.log4j.Logger; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.converter.HttpMessageNotReadableException; 8 | import org.springframework.web.HttpMediaTypeNotSupportedException; 9 | import org.springframework.web.HttpRequestMethodNotSupportedException; 10 | import org.springframework.web.bind.MethodArgumentNotValidException; 11 | import org.springframework.web.bind.annotation.ControllerAdvice; 12 | import org.springframework.web.bind.annotation.ExceptionHandler; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | import org.springframework.web.bind.annotation.ResponseStatus; 15 | 16 | import javax.validation.ValidationException; 17 | 18 | 19 | /** 20 | * 全局异常处理切面 21 | * @author leeyom 22 | * @date 2017年10月19日 10:41 23 | */ 24 | 25 | @ControllerAdvice 26 | @ResponseBody 27 | public class ExceptionAspect { 28 | 29 | private static final Logger log = Logger.getLogger(ExceptionAspect.class); 30 | 31 | /** 32 | * 400 - Bad Request 33 | */ 34 | @ResponseStatus(HttpStatus.BAD_REQUEST) 35 | @ExceptionHandler(HttpMessageNotReadableException.class) 36 | public ResultBean handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { 37 | ResultBean resultBean = new ResultBean(); 38 | resultBean.setCode(400); 39 | resultBean.setMsg("Could not read json..."); 40 | log.error("Could not read json...", e); 41 | return resultBean; 42 | } 43 | 44 | /** 45 | * 400 - Bad Request 46 | */ 47 | @ResponseStatus(HttpStatus.BAD_REQUEST) 48 | @ExceptionHandler({MethodArgumentNotValidException.class}) 49 | public ResultBean handleValidationException(MethodArgumentNotValidException e) { 50 | ResultBean resultBean = new ResultBean(); 51 | resultBean.setCode(400); 52 | resultBean.setMsg("参数检验异常!"); 53 | log.error("参数检验异常!", e); 54 | return resultBean; 55 | } 56 | 57 | /** 58 | * 405 - Method Not Allowed。HttpRequestMethodNotSupportedException 59 | * 是ServletException的子类,需要Servlet API支持 60 | */ 61 | @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) 62 | @ExceptionHandler(HttpRequestMethodNotSupportedException.class) 63 | public ResultBean handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { 64 | ResultBean resultBean = new ResultBean(); 65 | resultBean.setCode(405); 66 | resultBean.setMsg("请求方法不支持!"); 67 | log.error("请求方法不支持!", e); 68 | return resultBean; 69 | } 70 | 71 | /** 72 | * 415 - Unsupported Media Type。HttpMediaTypeNotSupportedException 73 | * 是ServletException的子类,需要Servlet API支持 74 | */ 75 | @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) 76 | @ExceptionHandler({HttpMediaTypeNotSupportedException.class}) 77 | public ResultBean handleHttpMediaTypeNotSupportedException(Exception e) { 78 | ResultBean resultBean = new ResultBean(); 79 | resultBean.setCode(415); 80 | resultBean.setMsg("内容类型不支持!"); 81 | log.error("内容类型不支持!", e); 82 | return resultBean; 83 | } 84 | 85 | /** 86 | * 401 - Internal Server Error 87 | */ 88 | @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 89 | @ExceptionHandler(TokenException.class) 90 | public ResultBean handleTokenException(Exception e) { 91 | ResultBean resultBean = new ResultBean(); 92 | resultBean.setCode(401); 93 | resultBean.setMsg("Token已失效"); 94 | log.error("Token已失效", e); 95 | return resultBean; 96 | } 97 | 98 | /** 99 | * 500 - Internal Server Error 100 | */ 101 | @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 102 | @ExceptionHandler(Exception.class) 103 | public ResultBean handleException(Exception e) { 104 | ResultBean resultBean = new ResultBean(); 105 | resultBean.setCode(500); 106 | resultBean.setMsg("内部服务器错误!"); 107 | log.error("内部服务器错误!", e); 108 | return resultBean; 109 | } 110 | 111 | /** 112 | * 400 - Bad Request 113 | */ 114 | @ResponseStatus(HttpStatus.BAD_REQUEST) 115 | @ExceptionHandler(ValidationException.class) 116 | public ResultBean handleValidationException(ValidationException e) { 117 | ResultBean resultBean = new ResultBean(); 118 | resultBean.setCode(400); 119 | resultBean.setMsg("参数验证失败!"); 120 | log.error("参数验证失败!", e); 121 | return resultBean; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/handler/HomeHandler.java: -------------------------------------------------------------------------------- 1 | package com.artisan.handler; 2 | 3 | 4 | import com.artisan.authorization.manager.TokenManager; 5 | import com.artisan.authorization.model.TokenModel; 6 | import com.artisan.common.annotation.IgnoreSecurity; 7 | import com.artisan.common.constant.StatusCode; 8 | import com.artisan.common.utils.Base64Util; 9 | import com.artisan.pojo.db.User; 10 | import com.artisan.pojo.vo.ResultBean; 11 | import com.artisan.pojo.vo.UserVO; 12 | import io.swagger.annotations.Api; 13 | import io.swagger.annotations.ApiImplicitParam; 14 | import io.swagger.annotations.ApiImplicitParams; 15 | import io.swagger.annotations.ApiOperation; 16 | import org.apache.log4j.Logger; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.stereotype.Controller; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | import org.springframework.web.bind.annotation.RequestMethod; 21 | import org.springframework.web.bind.annotation.RequestParam; 22 | import org.springframework.web.bind.annotation.ResponseBody; 23 | 24 | /** 25 | * 平台登录登出 26 | * @author Leeyom Wang 27 | * @date 2017年10月19日 12:06 28 | */ 29 | @Api(description = "平台登录注册", tags = "HomeHandler", basePath = "/home") 30 | @Controller 31 | @RequestMapping("/home") 32 | public class HomeHandler extends BaseHandler { 33 | 34 | private static final Logger LOGGER = Logger.getLogger(HomeHandler.class); 35 | 36 | @Autowired 37 | private TokenManager tokenManager; 38 | 39 | /** 40 | * 登录 41 | * @param userName 用户名 42 | * @param password 密码,MD5加密 43 | * @return 登录结果信息 44 | */ 45 | @ApiOperation(value = "用户登录", notes = "用户登录") 46 | @RequestMapping(value = "/login", method = RequestMethod.POST) 47 | @ApiImplicitParams({ 48 | @ApiImplicitParam(paramType = "query", name = "userName", value = "用户名", required = true, dataType = "String"), 49 | @ApiImplicitParam(paramType = "query", name = "password", value = "用户密码", required = true, dataType = "String"), 50 | }) 51 | @ResponseBody 52 | @IgnoreSecurity 53 | public ResultBean login(@RequestParam(value = "userName") String userName, @RequestParam(value = "password") String password) { 54 | ResultBean resultBean = new ResultBean(); 55 | UserVO userVO = new UserVO(); 56 | try { 57 | User user = userService.getUser(userName, password); 58 | if (user == null) { 59 | resultBean.setCode(StatusCode.HTTP_FAILURE); 60 | resultBean.setMsg("Login failed, user name or password error!"); 61 | } else { 62 | TokenModel token; 63 | // 判断用户是否已经登录过,如果登录过,就将redis缓存中的token删除,重新创建新的token值,保证一个用户在一个时间段只有一个可用 Token 64 | if (tokenManager.hasToken(user.getuId())) { 65 | //清除过时的token 66 | tokenManager.deleteToken(user.getuId()); 67 | //创建token 68 | token = tokenManager.createToken(user.getuId()); 69 | } else { 70 | //创建token 71 | token = tokenManager.createToken(user.getuId()); 72 | } 73 | 74 | userVO.setuId(user.getuId()); 75 | userVO.setuName(user.getUserName()); 76 | userVO.setAge(user.getAge()); 77 | userVO.setBirthday(user.getBirthday()); 78 | userVO.setSex(user.getSex()); 79 | //将token返回给客户端 80 | userVO.setToken(Base64Util.encodeData(token.getToken())); 81 | resultBean.setData(userVO); 82 | } 83 | } catch (Exception e) { 84 | resultBean.setCode(StatusCode.HTTP_FAILURE); 85 | resultBean.setMsg("Login failed, user name or password error!"); 86 | LOGGER.error("用户登录失败!参数信息:userName = " + userName + ",password = " + password, e); 87 | e.printStackTrace(); 88 | } 89 | return resultBean; 90 | } 91 | 92 | /** 93 | * 登出 94 | * @param userId 用户id 95 | * @return 96 | */ 97 | @ApiOperation(value = "用户登出", notes = "用户登出") 98 | @RequestMapping(value = "/logout", method = RequestMethod.POST) 99 | @ApiImplicitParams({ 100 | @ApiImplicitParam(paramType = "query", name = "userId", value = "用户id", required = true, dataType = "long") 101 | }) 102 | @IgnoreSecurity 103 | @ResponseBody 104 | public ResultBean logout(@RequestParam(value = "userId") Long userId) { 105 | ResultBean resultBean = new ResultBean(); 106 | try { 107 | tokenManager.deleteToken(userId); 108 | } catch (Exception e) { 109 | resultBean.setCode(StatusCode.HTTP_FAILURE); 110 | resultBean.setMsg("Logout failed!"); 111 | LOGGER.error("遇到未知错误,退出失败!", e); 112 | } 113 | return resultBean; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/handler/UserHandler.java: -------------------------------------------------------------------------------- 1 | package com.artisan.handler; 2 | 3 | import com.artisan.common.constant.StatusCode; 4 | import com.artisan.pojo.db.User; 5 | import com.artisan.pojo.vo.ResultBean; 6 | import io.swagger.annotations.*; 7 | import org.apache.log4j.Logger; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.validation.BindingResult; 10 | import org.springframework.validation.ObjectError; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import javax.validation.Valid; 14 | import java.util.List; 15 | 16 | /** 17 | * 用户管理 18 | * @author Leeyom Wang 19 | * @date 2017年10月26日 15:20 20 | */ 21 | @Api(description = "user管理", tags = "UserHandler", basePath = "/users") 22 | @Controller 23 | @RequestMapping("/users") 24 | public class UserHandler extends BaseHandler { 25 | 26 | private static final Logger LOGGER = Logger.getLogger(UserHandler.class); 27 | 28 | @ApiOperation(value = "查询列表") 29 | @RequestMapping(value = "/", method = RequestMethod.GET) 30 | @ResponseBody 31 | public ResultBean getUserList() { 32 | ResultBean resultBean = new ResultBean(); 33 | try { 34 | List userList = userService.selectAll(); 35 | resultBean.setData(userList); 36 | } catch (Exception e) { 37 | resultBean.setCode(StatusCode.HTTP_FAILURE); 38 | resultBean.setMsg("Request User list Failed!"); 39 | LOGGER.error("查询列表失败!", e); 40 | } 41 | return resultBean; 42 | } 43 | 44 | @ApiOperation(value = "根据id查询指定的User") 45 | @ApiImplicitParams({ 46 | @ApiImplicitParam(name = "id", value = "id", required = true, defaultValue = "", dataType = "int", paramType = "path"), 47 | }) 48 | @ResponseBody 49 | @RequestMapping(value = "/{id}", method = RequestMethod.GET) 50 | public ResultBean getUser(@PathVariable("id") Integer id) { 51 | ResultBean resultBean = new ResultBean(); 52 | try { 53 | User user = userService.selectByPrimaryKey(id); 54 | resultBean.setData(user); 55 | } catch (Exception e) { 56 | resultBean.setCode(StatusCode.HTTP_FAILURE); 57 | resultBean.setMsg("Failed to request User details!"); 58 | LOGGER.error("查询指定的User失败!参数信息:id = " + id, e); 59 | } 60 | return resultBean; 61 | } 62 | 63 | @ApiOperation(value = "新增User") 64 | @ResponseBody 65 | @RequestMapping(value = "/", method = RequestMethod.POST) 66 | public ResultBean add(@ApiParam(value = "新增User实体", required = true) @RequestBody @Valid User user, BindingResult result) { 67 | ResultBean resultBean = new ResultBean(); 68 | StringBuilder errorMsg = new StringBuilder(""); 69 | if (result.hasErrors()) { 70 | List list = result.getAllErrors(); 71 | for (ObjectError error : list) { 72 | errorMsg = errorMsg.append(error.getCode()).append("-").append(error.getDefaultMessage()).append(";"); 73 | } 74 | resultBean.setCode(StatusCode.HTTP_FAILURE); 75 | resultBean.setData(errorMsg.toString()); 76 | return resultBean; 77 | } 78 | try { 79 | userService.insert(user); 80 | } catch (Exception e) { 81 | resultBean.setCode(StatusCode.HTTP_FAILURE); 82 | resultBean.setMsg("新增User失败!"); 83 | LOGGER.error("新增User失败!参数信息:User = " + user.toString(), e); 84 | } 85 | return resultBean; 86 | } 87 | 88 | @ApiOperation(value = "更新指定的User") 89 | @ApiImplicitParams({ 90 | @ApiImplicitParam(name = "id", value = "id", required = true, defaultValue = "", dataType = "int", paramType = "path"), 91 | }) 92 | @ResponseBody 93 | @RequestMapping(value = "/{id}", method = RequestMethod.PUT) 94 | public ResultBean update(@PathVariable("id") Integer id, @ApiParam(value = "更新User详细信息", required = true) @RequestBody User user) { 95 | ResultBean resultBean = new ResultBean(); 96 | try { 97 | User oldUser = userService.selectByPrimaryKey(id); 98 | oldUser.setAge(user.getAge()); 99 | oldUser.setBirthday(user.getBirthday()); 100 | oldUser.setPassword(user.getPassword()); 101 | oldUser.setSex(user.getSex()); 102 | oldUser.setUserName(user.getUserName()); 103 | userService.updateByPrimaryKey(oldUser); 104 | } catch (Exception e) { 105 | resultBean.setCode(StatusCode.HTTP_FAILURE); 106 | resultBean.setMsg("Update User failed!"); 107 | LOGGER.error("更新失败!参数信息:id = " + id + ",User = " + user.toString(), e); 108 | } 109 | return resultBean; 110 | } 111 | 112 | @ApiOperation(value = "根据id物理删除指定的User,需谨慎!") 113 | @ApiImplicitParams({ 114 | @ApiImplicitParam(name = "id", value = "id", required = true, defaultValue = "", dataType = "int", paramType = "path"), 115 | }) 116 | @ResponseBody 117 | @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) 118 | public ResultBean delete(@PathVariable("id") Integer id) { 119 | ResultBean resultBean = new ResultBean(); 120 | try { 121 | userService.deleteByPrimaryKey(id); 122 | } catch (Exception e) { 123 | resultBean.setCode(StatusCode.HTTP_FAILURE); 124 | resultBean.setMsg("Delete User failed!"); 125 | e.printStackTrace(); 126 | LOGGER.error("删除失败!参数信息:id = " + id, e); 127 | } 128 | return resultBean; 129 | } 130 | 131 | } 132 | 133 | -------------------------------------------------------------------------------- /src/main/resources/spring/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | classpath:config.properties 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | classpath:mapper/*.xml 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/utils/DateUtils.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.utils; 2 | 3 | import java.text.DateFormat; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.ArrayList; 7 | import java.util.Calendar; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | /** 12 | * 日期工具类 13 | * @author Leeyom Wang 14 | * @date 2017年10月19日 12:05 15 | */ 16 | public class DateUtils { 17 | 18 | private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); 19 | private static final SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 20 | 21 | /** 22 | * 将日期转化为指定格式的字符串 23 | * @param date 需要转化的日期 24 | * @param pattern 转化规则 25 | * @return 指定格式的日期字符串 26 | */ 27 | public static String getString(Date date, String pattern) { 28 | DateFormat df = new SimpleDateFormat(pattern); 29 | return df.format(date); 30 | } 31 | 32 | /** 33 | * 将日期字符串转换为指定格式的日期对象 34 | * @param strDate 日期字符串 35 | * @param format 转化规则 36 | * @return 指定格式的日期对象 37 | */ 38 | public static Date getDate(String strDate, String format) { 39 | DateFormat df = new SimpleDateFormat(format); 40 | try { 41 | return df.parse(strDate); 42 | } catch (ParseException e) { 43 | throw new IllegalArgumentException("Can't parse " + strDate + " using " + format); 44 | } 45 | } 46 | 47 | /** 48 | * 获取两个日期对象之间相差的天数 49 | * @param beginDate 开始时间 50 | * @param endDate 结束时间 51 | * @return 相差天数 52 | */ 53 | public static int getDays(Date beginDate, Date endDate) { 54 | int days = -1; 55 | long beginMillisecond = beginDate.getTime(); 56 | long endMillisecond = endDate.getTime(); 57 | long millisecondForDay = 24 * 60 * 60 * 1000; 58 | days = (int) ((endMillisecond - beginMillisecond) / millisecondForDay); 59 | return days; 60 | } 61 | 62 | /** 63 | * 获得两个日期对象之间相差的小时数 64 | * @param beginDate 开始时间 65 | * @param endDate 结束时间 66 | * @return 相差小时 67 | */ 68 | public static long getTimes(Date beginDate, Date endDate) { 69 | long time = -1; 70 | long beginMillisecond = beginDate.getTime(); 71 | long endMillisecond = endDate.getTime(); 72 | long millisecondForDay = 60 * 60 * 1000; 73 | time = (long) ((endMillisecond - beginMillisecond) / millisecondForDay); 74 | return time; 75 | } 76 | 77 | /** 78 | * 指定的日期加上或者减去指定的天数 79 | * @param date 日期 80 | * @param day 天数 81 | * @return 修改后的日期 82 | */ 83 | public static Date addDays(Date date, int day) { 84 | Calendar calendar = Calendar.getInstance(); 85 | calendar.setTime(date); 86 | calendar.add(Calendar.DATE, day); 87 | return calendar.getTime(); 88 | } 89 | 90 | /** 91 | * 判断当前时间是上午还是下午 92 | * @param date 日期 93 | * @return 上午or下午 94 | */ 95 | public static String getAmOrPm(Date date) { 96 | String str = ""; 97 | Calendar calendar = Calendar.getInstance(); 98 | calendar.setTime(date); 99 | int num = calendar.get(Calendar.AM_PM); 100 | if (num == 0) { 101 | str = "上午"; 102 | } else if (num == 1) { 103 | str = "下午"; 104 | } 105 | return str; 106 | } 107 | 108 | /** 109 | * 获取指定时间的星期数 110 | * @param date 日期 111 | * @return 例如:星期一 112 | */ 113 | public static String getStrWeek(Date date) { 114 | String strWeek = ""; 115 | Calendar calendar = Calendar.getInstance(); 116 | calendar.setTime(date); 117 | int weekNum = calendar.get(Calendar.DAY_OF_WEEK); 118 | if (weekNum == 1) { 119 | strWeek = "星期天"; 120 | } else if (weekNum == 2) { 121 | strWeek = "星期一"; 122 | } else if (weekNum == 3) { 123 | strWeek = "星期二"; 124 | } else if (weekNum == 4) { 125 | strWeek = "星期三"; 126 | } else if (weekNum == 5) { 127 | strWeek = "星期四"; 128 | } else if (weekNum == 6) { 129 | strWeek = "星期五"; 130 | } else if (weekNum == 7) { 131 | strWeek = "星期六"; 132 | } 133 | return strWeek; 134 | } 135 | 136 | /** 137 | * 获取指定时间的星期数 138 | * @param date 139 | * @return 例如:1 140 | */ 141 | public static int getIntWeek(Date date) { 142 | int intWeek = 0; 143 | Calendar calendar = Calendar.getInstance(); 144 | calendar.setTime(date); 145 | int weekNum = calendar.get(Calendar.DAY_OF_WEEK); 146 | if (weekNum == 1) { 147 | intWeek = 7; 148 | } else if (weekNum == 2) { 149 | intWeek = 1; 150 | } else if (weekNum == 3) { 151 | intWeek = 2; 152 | } else if (weekNum == 4) { 153 | intWeek = 3; 154 | } else if (weekNum == 5) { 155 | intWeek = 4; 156 | } else if (weekNum == 6) { 157 | intWeek = 5; 158 | } else if (weekNum == 7) { 159 | intWeek = 6; 160 | } 161 | return intWeek; 162 | } 163 | 164 | /** 165 | * 获取当前时间的下个星期一 166 | * @return 下个星期一的Date对象 167 | */ 168 | public static Date getNextMonday() { 169 | Date date = new Date(); 170 | int w = getIntWeek(date); 171 | if (w == 1) { 172 | return addDays(date, 7); 173 | } 174 | if (w == 2) { 175 | return addDays(date, 6); 176 | } 177 | if (w == 3) { 178 | return addDays(date, 5); 179 | } 180 | if (w == 4) { 181 | return addDays(date, 4); 182 | } 183 | if (w == 5) { 184 | return addDays(date, 3); 185 | } 186 | if (w == 6) { 187 | return addDays(date, 2); 188 | } 189 | return null; 190 | } 191 | 192 | /** 193 | * 获取当月第一天 194 | * @return 195 | */ 196 | public static String getFirstDayOfMonth() { 197 | String str = ""; 198 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); 199 | Calendar lastDate = Calendar.getInstance(); 200 | lastDate.set(Calendar.DATE, 1);// 设为当前月的1 号 201 | str = sdf.format(lastDate.getTime()); 202 | return str; 203 | } 204 | 205 | /** 206 | * 获取上月第一天 207 | * @return 208 | */ 209 | public static String getPreviousMonthFirst() { 210 | String str = ""; 211 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 212 | Calendar lastDate = Calendar.getInstance(); 213 | lastDate.set(Calendar.DATE, 1);// 设为当前月的1 号 214 | lastDate.add(Calendar.MONTH, -1);// 减一个月,变为下月的1 号 215 | // lastDate.add(Calendar.DATE,-1);//减去一天,变为当月最后一天 216 | str = sdf.format(lastDate.getTime()); 217 | return str; 218 | } 219 | 220 | /** 221 | * 获得上月最后一天的日期 222 | * @return 223 | */ 224 | public static String getPreviousMonthEnd() { 225 | String str = ""; 226 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 227 | Calendar lastDate = Calendar.getInstance(); 228 | lastDate.add(Calendar.MONTH, -1);// 减一个月 229 | lastDate.set(Calendar.DATE, 1);// 把日期设置为当月第一天 230 | lastDate.roll(Calendar.DATE, -1);// 日期回滚一天,也就是本月最后一天 231 | str = sdf.format(lastDate.getTime()); 232 | return str; 233 | } 234 | 235 | /** 236 | * 获取给定的两个日期之间的所有的Date 237 | * @param startDate 开始时间 238 | * @param endDate 结束时间 239 | * @return 日期结果集 240 | * @throws Exception 开始时间大于结束时间的异常 241 | */ 242 | public static List dateSplit(Date startDate, Date endDate) throws Exception { 243 | if (!startDate.before(endDate)) 244 | throw new Exception("开始时间应该在结束时间之后"); 245 | Long spi = endDate.getTime() - startDate.getTime(); 246 | Long step = spi / (24 * 60 * 60 * 1000);// 相隔天数 247 | 248 | List dateList = new ArrayList(); 249 | dateList.add(endDate); 250 | for (int i = 1; i <= step; i++) { 251 | dateList.add(new Date(dateList.get(i - 1).getTime() - (24 * 60 * 60 * 1000)));// 比上一天减一 252 | } 253 | return dateList; 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /src/main/java/com/artisan/common/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.artisan.common.utils; 2 | 3 | import sun.misc.BASE64Decoder; 4 | 5 | import java.io.UnsupportedEncodingException; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Vector; 9 | 10 | /** 11 | * 字符串处理工具类 12 | * @author Leeyom Wang 13 | * @date 2017年10月19日 11:53 14 | */ 15 | public class StringUtils { 16 | /** 17 | * 将String数组转换为String字符串 18 | * @param strArray 要处理的String数组 19 | * @return 字符串 20 | */ 21 | public static String array2String(String[] strArray) { 22 | 23 | StringBuffer strBuffer = new StringBuffer(); 24 | 25 | for (int i = 0; i < strArray.length; i++) { 26 | strBuffer.append(strArray[i]); 27 | } 28 | return strBuffer.toString(); 29 | } 30 | 31 | /** 32 | * 以type为分界符分离str字符,返回分离后的数组 33 | * @param str 待处理字符串 34 | * @param type 分界符 35 | * @return array 处理后的字符串数数组 36 | */ 37 | public static String[] split(String str, String type) { 38 | int begin = 0; 39 | int pos = 0; 40 | String tempstr = ""; 41 | String[] array = null; 42 | Vector vec = null; 43 | int len = str.trim().length(); 44 | str = str + type; 45 | 46 | if (len > 0) { 47 | while (str.length() > 0) { 48 | 49 | if (vec == null) { 50 | vec = new Vector(); 51 | } 52 | pos = str.indexOf(type, begin); 53 | tempstr = str.substring(begin, pos); 54 | str = str.substring(pos + type.length(), str.length()); 55 | vec.add(tempstr); 56 | } 57 | } 58 | if (vec != null) { 59 | array = new String[vec.size()]; 60 | for (int i = 0; i < vec.size(); i++) { 61 | array[i] = (String) vec.get(i); 62 | } 63 | } else { 64 | array = new String[0]; 65 | } 66 | return array; 67 | } 68 | 69 | /** 70 | * 判断字符串是否为null 71 | * @param s 要判断字符串对象 72 | * @return true 表示不为null false 为空 73 | * @throws Exception 74 | */ 75 | public static boolean notNull(String s) { 76 | if (s == null || s.trim().length() <= 0 || "".equals(s) || "null".equals(s)) { 77 | return false; 78 | } else { 79 | return true; 80 | } 81 | } 82 | 83 | /** 84 | * 判断两个字符胡灿是否相等 85 | * @param objstr 字符串 86 | * @param bjstr 字符串 87 | * @return false 表示不相等 true 相等 88 | * @throws Exception 89 | */ 90 | public static boolean equals(String objstr, String bjstr) { 91 | boolean lean = false; 92 | lean = (objstr != null) && objstr.equals(bjstr); 93 | return lean; 94 | } 95 | 96 | /** 97 | * 替换source中的str1为str2 98 | * @param source 待替换的字符串 99 | * @param str1 待替换的字符 100 | * @param str2 替换的字符串 101 | * @return java.lang.String 替换后的字符串 102 | */ 103 | public static String replace(String source, char str1, String str2) { 104 | return replace(source, String.valueOf(str1), str2); 105 | } 106 | 107 | /** 108 | * 替换source中的str1为str2 109 | * @param source 待替换的字符串 110 | * @param str1 待替换的部分字符串 111 | * @param str2 替换的字符串 112 | * @return java.lang.String 替换后的字符串 113 | */ 114 | public static String replace(String source, String str1, String str2) { 115 | if (source == null) 116 | return ""; 117 | String desc = ""; 118 | int posstart = 0; 119 | int posend = source.indexOf(str1, 0); 120 | int len = source.length(); 121 | while (posend >= 0 && posstart < len) { 122 | desc += source.substring(posstart, posend) + str2; 123 | posstart = posend + str1.length(); 124 | posend = source.indexOf(str1, posstart); 125 | } 126 | if (posstart < len) 127 | desc += source.substring(posstart, len); 128 | return desc; 129 | } 130 | 131 | /** 132 | * 将字符串列表转换成字符串数组 133 | * @param list List 字符串列表 134 | * @return String[] 字符串数组 135 | */ 136 | public static String[] list2Array(List list) { 137 | String[] strs = new String[list.size()]; 138 | for (int i = 0; i < strs.length; i++) { 139 | strs[i] = (String) list.get(i); 140 | } 141 | return strs; 142 | } 143 | 144 | /** 145 | * 将字符串数组转换成字符串列表 146 | * @param array String[] array 字符串数组 147 | * @return List 字符串列表集合 148 | */ 149 | public static List array2List(String[] array) { 150 | List list = new ArrayList(); 151 | if (array != null) { 152 | for (int i = 0; i < array.length; i++) { 153 | list.add(array[i]); 154 | } 155 | } 156 | return list; 157 | } 158 | 159 | /** 160 | * 过滤Html的特殊字 161 | * @param in 162 | * @return 163 | */ 164 | public static String htmlEscape(String in) { 165 | StringBuffer out = new StringBuffer(); 166 | for (int i = 0; i < in.length(); i++) { 167 | char c = in.charAt(i); 168 | switch (c) { 169 | case '"': 170 | out.append("""); 171 | break; 172 | case '&': 173 | out.append("&"); 174 | break; 175 | case '<': 176 | out.append("<"); 177 | break; 178 | case '>': 179 | out.append(">"); 180 | break; 181 | default: 182 | out.append(c); 183 | break; 184 | } 185 | } 186 | return out.toString(); 187 | } 188 | 189 | /** 190 | * 将字符串中的大写字母转化为"_"加小写字母 191 | * @param sentence 192 | * @return 193 | */ 194 | public static String capTurn(String sentence) { 195 | char[] retChars = sentence.toCharArray(); 196 | String retString = ""; 197 | for (int i = 0; i < retChars.length; i++) { 198 | char curchar = retChars[i]; 199 | 200 | if (Character.isUpperCase(curchar)) { 201 | retString = retString + "_" + Character.toLowerCase(curchar); 202 | } else { 203 | retString = retString + curchar; 204 | } 205 | } 206 | return retString; 207 | } 208 | 209 | /** 210 | * 把文本编码为Html代码 211 | * @param target 目标字符串 212 | * @return 编码后的字符串 213 | */ 214 | public static String htmEncode(String target) { 215 | StringBuffer stringbuffer = new StringBuffer(); 216 | int j = target.length(); 217 | for (int i = 0; i < j; i++) { 218 | char c = target.charAt(i); 219 | switch (c) { 220 | case 60: 221 | stringbuffer.append("<"); 222 | break; 223 | case 62: 224 | stringbuffer.append(">"); 225 | break; 226 | case 38: 227 | stringbuffer.append("&"); 228 | break; 229 | case 34: 230 | stringbuffer.append("""); 231 | break; 232 | case 169: 233 | stringbuffer.append("©"); 234 | break; 235 | case 174: 236 | stringbuffer.append("®"); 237 | break; 238 | case 165: 239 | stringbuffer.append("¥"); 240 | break; 241 | case 8364: 242 | stringbuffer.append("€"); 243 | break; 244 | case 8482: 245 | stringbuffer.append("™"); 246 | break; 247 | case 13: 248 | if (i < j - 1 && target.charAt(i + 1) == 10) { 249 | stringbuffer.append("
"); 250 | i++; 251 | } 252 | break; 253 | case 32: 254 | if (i < j - 1 && target.charAt(i + 1) == ' ') { 255 | stringbuffer.append("  "); 256 | i++; 257 | break; 258 | } 259 | default: 260 | stringbuffer.append(c); 261 | break; 262 | } 263 | } 264 | return new String(stringbuffer.toString()); 265 | } 266 | 267 | /** 268 | * base64解码 269 | * @param context 270 | * @return 271 | */ 272 | public static String decodeString(String context) { 273 | BASE64Decoder decoder = new BASE64Decoder(); 274 | try { 275 | byte[] fileNameStr = decoder.decodeBuffer(context); 276 | context = new String(fileNameStr, "UTF-8"); 277 | } catch (Exception e) { 278 | e.printStackTrace(); 279 | } 280 | return context; 281 | } 282 | 283 | /** 284 | * base64编码 285 | * @param str 286 | * @return 287 | */ 288 | public static String encodeString(String str) { 289 | String base64Str = null; 290 | try { 291 | base64Str = new sun.misc.BASE64Encoder().encode(str.getBytes("UTF-8")); 292 | } catch (UnsupportedEncodingException e) { 293 | e.printStackTrace(); 294 | } 295 | return base64Str; 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /src/main/resources/code_artisan.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : MySQL 5 | Source Server Type : MySQL 6 | Source Server Version : 50716 7 | Source Host : 127.0.0.1 8 | Source Database : code_artisan 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 50716 12 | File Encoding : utf-8 13 | 14 | Date: 11/02/2017 22:52:23 PM 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for `file` 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `file`; 24 | CREATE TABLE `file` ( 25 | `f_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 26 | `file_name` varchar(45) NOT NULL COMMENT '文件名', 27 | `file_url` varchar(45) NOT NULL COMMENT '文件路径', 28 | PRIMARY KEY (`f_id`), 29 | UNIQUE KEY `f_id_UNIQUE` (`f_id`) 30 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='文件表'; 31 | 32 | -- ---------------------------- 33 | -- Table structure for `file_permission` 34 | -- ---------------------------- 35 | DROP TABLE IF EXISTS `file_permission`; 36 | CREATE TABLE `file_permission` ( 37 | `f_id` int(11) NOT NULL COMMENT '文件主键id', 38 | `p_id` int(11) NOT NULL COMMENT '权限主键id', 39 | KEY `f_id_idx` (`f_id`), 40 | KEY `p_id_idx` (`p_id`), 41 | CONSTRAINT `f_id` FOREIGN KEY (`f_id`) REFERENCES `file` (`f_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 42 | CONSTRAINT `p_id_3` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 43 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='权限文件关联表'; 44 | 45 | -- ---------------------------- 46 | -- Table structure for `menu` 47 | -- ---------------------------- 48 | DROP TABLE IF EXISTS `menu`; 49 | CREATE TABLE `menu` ( 50 | `m_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 51 | `menu_name` varchar(45) NOT NULL COMMENT '菜单名称', 52 | `menu_url` varchar(45) NOT NULL COMMENT '菜单URL', 53 | `parent_m_id` int(11) DEFAULT NULL COMMENT '父级菜单', 54 | PRIMARY KEY (`m_id`), 55 | UNIQUE KEY `m_id_UNIQUE` (`m_id`) 56 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单表'; 57 | 58 | -- ---------------------------- 59 | -- Table structure for `menu_permission` 60 | -- ---------------------------- 61 | DROP TABLE IF EXISTS `menu_permission`; 62 | CREATE TABLE `menu_permission` ( 63 | `m_id` int(11) NOT NULL COMMENT '菜单主键', 64 | `p_id` int(11) NOT NULL COMMENT '权限主键', 65 | KEY `p_id_idx` (`p_id`), 66 | KEY `m_id_idx` (`m_id`), 67 | CONSTRAINT `m_id` FOREIGN KEY (`m_id`) REFERENCES `menu` (`m_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 68 | CONSTRAINT `p_id` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 69 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单和权限关联表'; 70 | 71 | -- ---------------------------- 72 | -- Table structure for `operation` 73 | -- ---------------------------- 74 | DROP TABLE IF EXISTS `operation`; 75 | CREATE TABLE `operation` ( 76 | `o_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 77 | `o_name` varchar(45) NOT NULL COMMENT '操作名称', 78 | `o_code` varchar(45) NOT NULL COMMENT '操作编码', 79 | `url` varchar(45) NOT NULL COMMENT '拦截的url', 80 | `parent_id` varchar(45) DEFAULT NULL COMMENT '父级操作id', 81 | PRIMARY KEY (`o_id`), 82 | UNIQUE KEY `o_id_UNIQUE` (`o_id`) 83 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='功能操作表'; 84 | 85 | -- ---------------------------- 86 | -- Table structure for `page` 87 | -- ---------------------------- 88 | DROP TABLE IF EXISTS `page`; 89 | CREATE TABLE `page` ( 90 | `page_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 91 | `page_code` varchar(45) NOT NULL COMMENT '页面元素编码', 92 | PRIMARY KEY (`page_id`), 93 | UNIQUE KEY `page_id_UNIQUE` (`page_id`) 94 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='页面元素表'; 95 | 96 | -- ---------------------------- 97 | -- Table structure for `page_permission` 98 | -- ---------------------------- 99 | DROP TABLE IF EXISTS `page_permission`; 100 | CREATE TABLE `page_permission` ( 101 | `page_id` int(11) NOT NULL COMMENT '页面主键', 102 | `p_id` int(11) NOT NULL COMMENT '权限主键', 103 | KEY `page_id_idx` (`page_id`), 104 | KEY `p_id_idx` (`p_id`), 105 | CONSTRAINT `p_id_2` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 106 | CONSTRAINT `page_id` FOREIGN KEY (`page_id`) REFERENCES `page` (`page_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 107 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='权限页面元素关联表'; 108 | 109 | -- ---------------------------- 110 | -- Table structure for `permission` 111 | -- ---------------------------- 112 | DROP TABLE IF EXISTS `permission`; 113 | CREATE TABLE `permission` ( 114 | `p_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 115 | `p_type_name` varchar(45) NOT NULL COMMENT '权限类型', 116 | PRIMARY KEY (`p_id`), 117 | UNIQUE KEY `p_id_UNIQUE` (`p_id`) 118 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='权限表'; 119 | 120 | -- ---------------------------- 121 | -- Table structure for `permission_operation` 122 | -- ---------------------------- 123 | DROP TABLE IF EXISTS `permission_operation`; 124 | CREATE TABLE `permission_operation` ( 125 | `p_id` int(11) NOT NULL, 126 | `o_id` int(11) NOT NULL, 127 | PRIMARY KEY (`p_id`,`o_id`), 128 | KEY `fk_permission_has_operation_operation1_idx` (`o_id`), 129 | KEY `fk_permission_has_operation_permission1_idx` (`p_id`), 130 | CONSTRAINT `fk_permission_has_operation_operation1` FOREIGN KEY (`o_id`) REFERENCES `operation` (`o_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 131 | CONSTRAINT `fk_permission_has_operation_permission1` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 132 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='权限和操作中间表'; 133 | 134 | -- ---------------------------- 135 | -- Table structure for `role` 136 | -- ---------------------------- 137 | DROP TABLE IF EXISTS `role`; 138 | CREATE TABLE `role` ( 139 | `r_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 140 | `role_name` varchar(45) NOT NULL COMMENT '角色名', 141 | PRIMARY KEY (`r_id`), 142 | UNIQUE KEY `r_id_UNIQUE` (`r_id`) 143 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色表'; 144 | 145 | -- ---------------------------- 146 | -- Table structure for `role_permission` 147 | -- ---------------------------- 148 | DROP TABLE IF EXISTS `role_permission`; 149 | CREATE TABLE `role_permission` ( 150 | `p_id` int(11) NOT NULL COMMENT '角色主键', 151 | `r_id` int(11) NOT NULL COMMENT '权限主键', 152 | PRIMARY KEY (`p_id`,`r_id`), 153 | KEY `fk_permission_has_role_role1_idx` (`r_id`), 154 | KEY `fk_permission_has_role_permission1_idx` (`p_id`), 155 | CONSTRAINT `fk_permission_has_role_permission1` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 156 | CONSTRAINT `fk_permission_has_role_role1` FOREIGN KEY (`r_id`) REFERENCES `role` (`r_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 157 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色权限中间表'; 158 | 159 | -- ---------------------------- 160 | -- Table structure for `user` 161 | -- ---------------------------- 162 | DROP TABLE IF EXISTS `user`; 163 | CREATE TABLE `user` ( 164 | `u_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 165 | `user_name` varchar(45) NOT NULL COMMENT '用户名', 166 | `password` varchar(45) NOT NULL COMMENT '密码', 167 | `birthday` date DEFAULT NULL COMMENT '生日', 168 | `sex` int(11) DEFAULT NULL COMMENT '性别', 169 | `age` int(11) DEFAULT NULL COMMENT '年龄', 170 | PRIMARY KEY (`u_id`), 171 | UNIQUE KEY `id_UNIQUE` (`u_id`) 172 | ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='用户表'; 173 | 174 | -- ---------------------------- 175 | -- Records of `user` 176 | -- ---------------------------- 177 | BEGIN; 178 | INSERT INTO `user` VALUES ('1', 'Leeyom', '123', '1993-08-26', '1', '24'), ('2', 'Tom', '5566', '1990-12-25', '1', '18'); 179 | COMMIT; 180 | 181 | -- ---------------------------- 182 | -- Table structure for `user_group` 183 | -- ---------------------------- 184 | DROP TABLE IF EXISTS `user_group`; 185 | CREATE TABLE `user_group` ( 186 | `group_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 187 | `group_name` varchar(45) NOT NULL COMMENT '用户组名称', 188 | `parent_group_name` varchar(45) NOT NULL COMMENT '父级用户组名称', 189 | PRIMARY KEY (`group_id`), 190 | UNIQUE KEY `group_id_UNIQUE` (`group_id`) 191 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户组'; 192 | 193 | -- ---------------------------- 194 | -- Table structure for `user_group_role` 195 | -- ---------------------------- 196 | DROP TABLE IF EXISTS `user_group_role`; 197 | CREATE TABLE `user_group_role` ( 198 | `group_id` int(11) NOT NULL COMMENT '用户组', 199 | `r_id` int(11) NOT NULL COMMENT '角色', 200 | PRIMARY KEY (`group_id`,`r_id`), 201 | KEY `fk_user_group_has_role_role1_idx` (`r_id`), 202 | KEY `fk_user_group_has_role_user_group1_idx` (`group_id`), 203 | CONSTRAINT `fk_user_group_has_role_role1` FOREIGN KEY (`r_id`) REFERENCES `role` (`r_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 204 | CONSTRAINT `fk_user_group_has_role_user_group1` FOREIGN KEY (`group_id`) REFERENCES `user_group` (`group_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 205 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户组和角色中间表'; 206 | 207 | -- ---------------------------- 208 | -- Table structure for `user_group_user` 209 | -- ---------------------------- 210 | DROP TABLE IF EXISTS `user_group_user`; 211 | CREATE TABLE `user_group_user` ( 212 | `group_id` int(11) NOT NULL COMMENT '用户组', 213 | `u_id` int(11) NOT NULL COMMENT '用户\n', 214 | PRIMARY KEY (`group_id`,`u_id`), 215 | KEY `fk_user_group_has_user_user1_idx` (`u_id`), 216 | KEY `fk_user_group_has_user_user_group1_idx` (`group_id`), 217 | CONSTRAINT `fk_user_group_has_user_user1` FOREIGN KEY (`u_id`) REFERENCES `user` (`u_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 218 | CONSTRAINT `fk_user_group_has_user_user_group1` FOREIGN KEY (`group_id`) REFERENCES `user_group` (`group_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 219 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户组和用户中间表'; 220 | 221 | -- ---------------------------- 222 | -- Table structure for `user_role` 223 | -- ---------------------------- 224 | DROP TABLE IF EXISTS `user_role`; 225 | CREATE TABLE `user_role` ( 226 | `u_id` int(11) NOT NULL COMMENT '用户id', 227 | `r_id` int(11) NOT NULL COMMENT '角色id', 228 | PRIMARY KEY (`u_id`,`r_id`), 229 | KEY `fk_user_has_role_role1_idx` (`r_id`), 230 | KEY `fk_user_has_role_user_idx` (`u_id`), 231 | CONSTRAINT `fk_user_has_role_role1` FOREIGN KEY (`r_id`) REFERENCES `role` (`r_id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 232 | CONSTRAINT `fk_user_has_role_user` FOREIGN KEY (`u_id`) REFERENCES `user` (`u_id`) ON DELETE NO ACTION ON UPDATE NO ACTION 233 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户角色中间表'; 234 | 235 | SET FOREIGN_KEY_CHECKS = 1; 236 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.leeyom 5 | code-artisan 6 | war 7 | 1.0-SNAPSHOT 8 | code-artisan 9 | http://www.leeyom.top 10 | 11 | 12 | 13 | 14 | junit 15 | junit 16 | 4.9 17 | test 18 | 19 | 20 | 21 | javax.servlet 22 | javax.servlet-api 23 | 3.1.0 24 | provided 25 | 26 | 27 | javax.servlet.jsp 28 | javax.servlet.jsp-api 29 | 2.3.1 30 | provided 31 | 32 | 33 | 34 | org.springframework 35 | spring-core 36 | 4.3.3.RELEASE 37 | 38 | 39 | org.springframework 40 | spring-web 41 | 4.3.3.RELEASE 42 | 43 | 44 | org.springframework 45 | spring-oxm 46 | 4.3.3.RELEASE 47 | 48 | 49 | org.springframework 50 | spring-context 51 | 4.3.3.RELEASE 52 | 53 | 54 | org.springframework 55 | spring-aop 56 | 4.3.3.RELEASE 57 | 58 | 59 | org.springframework 60 | spring-context-support 61 | 4.3.3.RELEASE 62 | 63 | 64 | org.springframework 65 | spring-webmvc 66 | 4.3.3.RELEASE 67 | 68 | 69 | org.springframework 70 | spring-jdbc 71 | 4.3.3.RELEASE 72 | 73 | 74 | org.springframework 75 | spring-tx 76 | 4.3.3.RELEASE 77 | 78 | 79 | org.springframework 80 | spring-test 81 | 4.3.3.RELEASE 82 | 83 | 84 | 85 | com.alibaba 86 | druid 87 | 1.1.5 88 | 89 | 90 | 91 | org.mybatis 92 | mybatis 93 | 3.2.8 94 | 95 | 96 | 97 | org.mybatis 98 | mybatis-spring 99 | 1.2.2 100 | 101 | 102 | 103 | mysql 104 | mysql-connector-java 105 | 5.1.42 106 | 107 | 108 | 109 | log4j 110 | log4j 111 | 1.2.17 112 | 113 | 114 | org.slf4j 115 | slf4j-api 116 | 1.7.21 117 | 118 | 119 | org.slf4j 120 | slf4j-log4j12 121 | 1.7.21 122 | 123 | 124 | 125 | com.google.code.gson 126 | gson 127 | 2.2.4 128 | 129 | 130 | net.sf.json-lib 131 | json-lib 132 | 2.4 133 | jdk15 134 | 135 | 136 | com.fasterxml.jackson.core 137 | jackson-core 138 | 2.6.2 139 | 140 | 141 | com.fasterxml.jackson.core 142 | jackson-databind 143 | 2.6.2 144 | 145 | 146 | com.fasterxml.jackson.core 147 | jackson-annotations 148 | 2.6.2 149 | 150 | 151 | 152 | commons-fileupload 153 | commons-fileupload 154 | 1.3.1 155 | 156 | 157 | commons-io 158 | commons-io 159 | 2.4 160 | 161 | 162 | commons-codec 163 | commons-codec 164 | 1.9 165 | 166 | 167 | 168 | io.springfox 169 | springfox-swagger2 170 | 2.4.0 171 | 172 | 173 | io.springfox 174 | springfox-swagger-ui 175 | 2.4.0 176 | 177 | 178 | 179 | redis.clients 180 | jedis 181 | 2.9.0 182 | 183 | 184 | org.springframework.data 185 | spring-data-redis 186 | 1.6.0.RELEASE 187 | 188 | 189 | 190 | org.aspectj 191 | aspectjrt 192 | 1.8.10 193 | 194 | 195 | org.aspectj 196 | aspectjweaver 197 | 1.8.10 198 | 199 | 200 | 201 | tk.mybatis 202 | mapper 203 | 3.4.4 204 | 205 | 206 | 207 | com.github.pagehelper 208 | pagehelper 209 | 4.1.4 210 | 211 | 212 | 213 | org.hibernate 214 | hibernate-validator 215 | 6.0.4.Final 216 | 217 | 218 | 219 | io.jsonwebtoken 220 | jjwt 221 | 0.9.0 222 | 223 | 224 | 225 | 226 | code-artisan 227 | 228 | 229 | 230 | org.apache.maven.plugins 231 | maven-compiler-plugin 232 | 233 | 1.8 234 | 1.8 235 | UTF-8 236 | 237 | 238 | 239 | 240 | org.mybatis.generator 241 | mybatis-generator-maven-plugin 242 | 1.3.2 243 | 244 | ${basedir}/src/main/resources/generator/generatorConfig.xml 245 | true 246 | true 247 | 248 | 249 | 250 | mysql 251 | mysql-connector-java 252 | ${mysql.version} 253 | 254 | 255 | tk.mybatis 256 | mapper 257 | ${mapper.version} 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | src/main/java 266 | 267 | **/*.properties 268 | **/*.xml 269 | 270 | false 271 | 272 | 273 | src/main/resources 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | UTF-8 282 | 1.8 283 | 1.8 284 | 1.8 285 | 286 | ${basedir}/src/main/java 287 | com.artisan.dao 288 | com.artisan.pojo.db 289 | 290 | ${basedir}/src/main/resources 291 | mapper 292 | 293 | 3.4.4 294 | 5.1.42 295 | 296 | 297 | 298 | --------------------------------------------------------------------------------