Commit d04afd4f by fsn

初始化

parent 153f2da4
git rm -r --cached .
git add .
git commit -m "update .gitignore"
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stylefeng</groupId>
<artifactId>guns</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>filco Maven Webapp</name>
<packaging>war</packaging>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.2.6.RELEASE</spring.version>
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.17</log4j.version>
<aspectj.version>1.8.9</aspectj.version>
<shiro.version>1.3.2</shiro.version>
</properties>
<dependencies>
<!-- mock数据和测试 -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- END -->
<!--二维码生成-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.1</version>
</dependency>
<!-- END -->
<!-- 生成persistence时用的模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
<!--END-->
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.0.2</version>
</dependency>
<!--END-->
<!--验证框架-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.2.Final</version>
</dependency>
<!--END-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- spring核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!--END-->
<!-- 数据库和连接池 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.21</version>
</dependency>
<!--END-->
<!-- 日志文件管理包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.23</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!--END-->
<!-- 格式化对象,方便输出日志 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.21</version>
</dependency>
<!--END-->
<!--shiro插件 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!--END-->
<!-- 模板引擎 -->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>2.7.0</version>
</dependency>
<!--END-->
</dependencies>
<build>
<finalName>guns</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/baseResources</directory>
</resource>
<resource>
<directory>src/main/resources/${package.environment}</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>dev</id>
<properties>
<package.environment>dev</package.environment>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>produce</id>
<properties>
<package.environment>produce</package.environment>
</properties>
</profile>
</profiles>
</project>
#开始结束占位符
DELIMITER_PLACEHOLDER_START=${
DELIMITER_PLACEHOLDER_END=}
#开始结束标签
DELIMITER_STATEMENT_START=@
DELIMITER_STATEMENT_END=null
#classpath 根路径
RESOURCE.root=/WEB-INF/view
#是否检测文件变化
RESOURCE.autoCheck=true
\ No newline at end of file
log4j.rootLogger=info,Console,File
#定义日志输出目的地为控制台
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
#可以灵活地指定日志输出格式,下面一行是指定具体的格式
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n
#文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.File = org.apache.log4j.RollingFileAppender
#指定输出目录
log4j.appender.File.File = logs/filco.log
#定义文件最大大小
log4j.appender.File.MaxFileSize = 100MB
# 输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志
log4j.appender.File.Threshold = ALL
log4j.appender.File.layout = org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n
\ No newline at end of file
package ${package.Entity};
#if(${activeRecord})
import com.baomidou.mybatisplus.activerecord.Model;
#end
#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
import java.io.Serializable;
import com.baomidou.mybatisplus.annotations.TableId;
/**
* <p>
* ${table.comment}
* </p>
*
* @author ${author}
* @since ${date}
*/
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#else
public class ${entity} implements Serializable {
#end
private static final long serialVersionUID = 1L;
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
/**
* ${field.comment}
*/
#end
#if(${field.convert})
#if(${field.keyFlag})
@TableId("${field.name}")
#else
@TableField("${field.name}")
#end
#else
#if(${field.keyFlag})
@TableId
#end
#end
private ${field.propertyType} ${field.propertyName};
#end
#foreach($field in ${table.fields})
#if(${field.propertyType.equals("Boolean")})
#set($getprefix="is")
#else
#set($getprefix="get")
#end
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
#if(${entityBuliderModel})
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#else
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#end
this.${field.propertyName} = ${field.propertyName};
#if(${entityBuliderModel})
return this;
#end
}
#end
#if(${entityColumnConstant})
#foreach($field in ${table.fields})
public static final String ${field.name.toUpperCase()} = "${field.name}";
#end
#end
#if(${activeRecord})
@Override
protected Serializable pkVal() {
#if(${keyPropertyName})
return this.${keyPropertyName};
#else
return this.id;
#end
}
#end
}
package com.stylefeng.guns.common.annotion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 统计系统调用次数的注解
*
* @author fengshuonan
* @date 2017年3月4日 下午11:53:28
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface CountStat {
String[] value() default {};
}
package com.stylefeng.guns.common.annotion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限注解 用于检查权限 规定访问权限
*
* @example @Permission({roleID1,roleID2})
* @example @Permission
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Permission {
String[] value() default {};
}
package com.stylefeng.guns.common.constant;
/**
* 系统常量
*
* @author fengshuonan
* @date 2017年2月12日 下午9:42:53
*/
public interface Const {
/**
* 系统默认的管理员密码
*/
String DEFAULT_PWD = "111111";
/**
* 管理员角色的名字
*/
String ADMIN_NAME = "administrator";
}
package com.stylefeng.guns.common.constant;
/**
* 多数据源的枚举
*
* @author fengshuonan
* @date 2017年3月5日 上午10:15:02
*/
public interface DSEnum {
String dataSourceGuns = "dataSourceGuns"; //Guns的数据源
}
package com.stylefeng.guns.common.constant.factory;
import com.stylefeng.guns.common.constant.state.*;
import com.stylefeng.guns.core.support.StrKit;
import com.stylefeng.guns.core.util.Convert;
import com.stylefeng.guns.core.util.SpringContextHolder;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.persistence.dao.DeptMapper;
import com.stylefeng.guns.persistence.dao.RoleMapper;
import com.stylefeng.guns.persistence.model.Dept;
import com.stylefeng.guns.persistence.model.Role;
/**
* 常量的生产工厂
*
* @author fengshuonan
* @date 2017年2月13日 下午10:55:21
*/
public class ConstantFactory {
private static RoleMapper roleMapper = SpringContextHolder.getBean(RoleMapper.class);
private static DeptMapper deptMapper = SpringContextHolder.getBean(DeptMapper.class);
/**
* 通过角色ids获取角色名称
*/
public static String getRoleName(String roleIds) {
Integer[] roles = Convert.toIntArray(roleIds);
StringBuilder sb = new StringBuilder();
for (int role : roles) {
Role roleObj = roleMapper.selectById(role);
if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
sb.append(roleObj.getName()).append(",");
}
}
return StrKit.removeSuffix(sb.toString(), ",");
}
/**
* 通过角色id获取角色名称
*/
public static String getSingleRoleName(Integer roleId) {
if (0 == roleId) {
return "--";
}
Role roleObj = roleMapper.selectById(roleId);
if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
return roleObj.getName();
}
return "";
}
/**
* 通过角色id获取角色英文名称
*/
public static String getSingleRoleTip(Integer roleId) {
if (0 == roleId) {
return "--";
}
Role roleObj = roleMapper.selectById(roleId);
if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
return roleObj.getTips();
}
return "";
}
/**
* 获取部门名称
*/
public static String getDeptName(Integer deptId) {
Dept dept = deptMapper.selectById(deptId);
if (ToolUtil.isNotEmpty(dept) && ToolUtil.isNotEmpty(dept.getFullname())) {
return dept.getFullname();
}
return "";
}
/**
* 获取性别名称
*/
public static String getSexName(Integer sex) {
return Sex.valueOf(sex);
}
/**
* 获取用户登录状态
*/
public static String getStatusName(Integer status) {
return ManagerStatus.valueOf(status);
}
/**
* 获取菜单状态
*/
public static String getMenuStatusName(Integer status) {
return MenuStatus.valueOf(status);
}
}
package com.stylefeng.guns.common.constant.state;
/**
* 管理员的装状态
*
* @author fengshuonan
* @Date 2017年1月10日 下午9:54:13
*/
public enum ManagerStatus {
OK(1, "启用"), FREEZED(2, "冻结"), WAIT(3, "待审核"), FORBID(4, "审核被拒绝"), DELETED(5, "被删除");
int code;
String message;
ManagerStatus(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public static String valueOf(Integer value) {
if (value == null) {
return "";
} else {
for (ManagerStatus ms : ManagerStatus.values()) {
if (ms.getCode() == value) {
return ms.getMessage();
}
}
return "";
}
}
}
package com.stylefeng.guns.common.constant.state;
/**
* 用户的状态
*
* @author fengshuonan
* @Date 2017年1月22日 下午12:14:59
*/
public enum MenuStatus {
ENABLE(1, "启用"),
DISABLE(2, "禁用");
int code;
String message;
MenuStatus(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public static String valueOf(Integer status) {
if (status == null) {
return "";
} else {
for (MenuStatus s : MenuStatus.values()) {
if (s.getCode() == status) {
return s.getMessage();
}
}
return "";
}
}
}
package com.stylefeng.guns.common.constant.state;
/**
* 性别
*
* @author fengshuonan
* @Date 2017年1月22日 下午12:14:59
*/
public enum Sex {
male(1, "男"), female(2, "女");
private Integer code;
private String des;
Sex(Integer code, String des) {
this.code = code;
this.des = des;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public static String valueOf(Integer value) {
if (value == null) {
return "";
} else {
for (Sex rt : Sex.values()) {
if (rt.getCode() == value) {
return rt.getDes();
}
}
return "";
}
}
}
package com.stylefeng.guns.common.constant.state;
/**
* 用户的状态
*
* @author fengshuonan
* @Date 2017年1月22日 下午12:14:59
*/
public enum UserStatus {
Login(1, "登录中"),
Exit(2, "退出"),
Locked(3, "锁定");
int code;
String message;
UserStatus(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public static String valueOf(Integer status) {
if (status == null) {
return "";
} else {
for (UserStatus s : UserStatus.values()) {
if (s.getCode() == status) {
return s.getMessage();
}
}
return "";
}
}
}
package com.stylefeng.guns.common.constant.tips;
import com.stylefeng.guns.common.exception.BizExceptionEnum;
/**
* 返回给前台的错误提示
*
* @author fengshuonan
* @date 2016年11月12日 下午5:05:22
*/
public class ErrorTip extends Tip {
public ErrorTip(int code, String message) {
super();
this.code = code;
this.message = message;
}
public ErrorTip(BizExceptionEnum bizExceptionEnum) {
this.code = bizExceptionEnum.getCode();
this.message = bizExceptionEnum.getMessage();
}
}
package com.stylefeng.guns.common.constant.tips;
/**
* 返回给前台的成功提示
*
* @author fengshuonan
* @date 2016年11月12日 下午5:05:22
*/
public class SuccessTip extends Tip{
public SuccessTip(){
super.code = 200;
super.message = "操作成功";
}
}
package com.stylefeng.guns.common.constant.tips;
/**
* 返回给前台的提示(最终转化为json形式)
*
* @author fengshuonan
* @Date 2017年1月11日 下午11:58:00
*/
public abstract class Tip {
protected int code;
protected String message;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package com.stylefeng.guns.common.controller;
import com.baomidou.mybatisplus.plugins.Page;
import com.stylefeng.guns.common.constant.Const;
import com.stylefeng.guns.common.constant.tips.SuccessTip;
import com.stylefeng.guns.common.page.PageInfoBT;
import com.stylefeng.guns.common.warpper.BaseControllerWarpper;
import com.stylefeng.guns.core.support.HttpKit;
import com.stylefeng.guns.core.util.FileUtil;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
@Component
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)
public class BaseController {
protected static String ADMIN_NAME = Const.ADMIN_NAME;
protected static String SUCCESS = "SUCCESS";
protected static String ERROR = "ERROR";
protected static String REDIRECT = "redirect:";
protected static String FORWARD = "forward:";
protected static SuccessTip SUCCESS_TIP = new SuccessTip();
protected HttpServletRequest getHttpServletRequest() {
return HttpKit.getRequest();
}
protected HttpServletResponse getHttpServletResponse() {
return HttpKit.getResponse();
}
protected HttpSession getSession() {
return HttpKit.getRequest().getSession();
}
protected String getPara(String name) {
return HttpKit.getRequest().getParameter(name);
}
protected void setAttr(String name, Object value) {
HttpKit.getRequest().setAttribute(name, value);
}
protected Integer getSystemInvokCount() {
return (Integer) this.getHttpServletRequest().getServletContext().getAttribute("systemCount");
}
/**
* 把service层的分页信息,封装为bootstrap table通用的分页封装
*/
protected <T> PageInfoBT<T> packForBT(Page<T> page) {
return new PageInfoBT<T>(page);
}
/**
* 包装一个list,让list增加额外属性
*/
protected Object warpObject(BaseControllerWarpper warpper) {
return warpper.warp();
}
/**
* 删除cookie
*/
protected void deletePhoneCookie(String cookieName) {
Cookie[] cookies = this.getHttpServletRequest().getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals(cookieName)) {
Cookie temp = new Cookie(cookie.getName(), "");
temp.setMaxAge(0);
this.getHttpServletResponse().addCookie(temp);
}
}
}
/**
* 返回前台文件流
*
* @author fengshuonan
* @date 2017年2月28日 下午2:53:19
*/
protected ResponseEntity<byte[]> renderFile(String fileName, String filePath) {
byte[] bytes = FileUtil.toByteArray2(filePath);
return renderFile(fileName, bytes);
}
/**
* 返回前台文件流
*
* @author fengshuonan
* @date 2017年2月28日 下午2:53:19
*/
protected ResponseEntity<byte[]> renderFile(String fileName, byte[] fileBytes) {
String dfileName = null;
try {
dfileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", dfileName);
return new ResponseEntity<byte[]>(fileBytes, headers, HttpStatus.CREATED);
}
}
package com.stylefeng.guns.common.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* 全局的控制器
*
* @author fengshuonan
* @date 2016年11月13日 下午11:04:45
*/
@Controller
@RequestMapping("/global")
public class GlobalController {
/**
* 跳转到404页面
*
* @author fengshuonan
*/
@RequestMapping(path = "/error", method = RequestMethod.GET)
public String errorPage() {
return "/404.html";
}
}
package com.stylefeng.guns.common.exception;
/**
* @Description 所有业务异常的枚举
* @author fengshuonan
* @date 2016年11月12日 下午5:04:51
*/
public enum BizExceptionEnum {
FILE_READING_ERROR(400,"FILE_READING_ERROR!"),
FILE_NOT_FOUND(400,"FILE_NOT_FOUND!"),
DB_RESOURCE_NULL(400,"数据库中没有该资源"),
NO_PERMITION(405, "无权访问该资源"),
USER_ALREADY_REG(401,"该用户已经注册"),
NO_THIS_USER(400,"没有此用户"),
REQUEST_INVALIDATE(400,"请求数据格式不正确"),
USER_NOT_EXISTED(400, "没有此用户"),
ACCOUNT_FREEZED(401, "账号被冻结"),
REQUEST_NULL(400, "请求为空"),
SERVER_ERROR(500, "服务器异常");
BizExceptionEnum(int code, String message) {
this.friendlyCode = code;
this.friendlyMsg = message;
}
BizExceptionEnum(int code, String message,String urlPath) {
this.friendlyCode = code;
this.friendlyMsg = message;
this.urlPath = urlPath;
}
private int friendlyCode;
private String friendlyMsg;
private String urlPath;
public int getCode() {
return friendlyCode;
}
public void setCode(int code) {
this.friendlyCode = code;
}
public String getMessage() {
return friendlyMsg;
}
public void setMessage(String message) {
this.friendlyMsg = message;
}
public String getUrlPath() {
return urlPath;
}
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
}
}
package com.stylefeng.guns.common.exception;
/**
* @Description 业务异常的封装
* @author fengshuonan
* @date 2016年11月12日 下午5:05:10
*/
@SuppressWarnings("serial")
public class BussinessException extends RuntimeException{
//友好提示的code码
private int friendlyCode;
//友好提示
private String friendlyMsg;
//业务异常跳转的页面
private String urlPath;
public BussinessException(BizExceptionEnum bizExceptionEnum){
this.friendlyCode = bizExceptionEnum.getCode();
this.friendlyMsg = bizExceptionEnum.getMessage();
this.urlPath = bizExceptionEnum.getUrlPath();
}
public int getCode() {
return friendlyCode;
}
public void setCode(int code) {
this.friendlyCode = code;
}
public String getMessage() {
return friendlyMsg;
}
public void setMessage(String message) {
this.friendlyMsg = message;
}
public String getUrlPath() {
return urlPath;
}
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
}
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.common.exception;
import com.stylefeng.guns.core.support.StrKit;
/**
* 工具类初始化异常
*/
public class ToolBoxException extends RuntimeException{
private static final long serialVersionUID = 8247610319171014183L;
public ToolBoxException(Throwable e) {
super(e.getMessage(), e);
}
public ToolBoxException(String message) {
super(message);
}
public ToolBoxException(String messageTemplate, Object... params) {
super(StrKit.format(messageTemplate, params));
}
public ToolBoxException(String message, Throwable throwable) {
super(message, throwable);
}
public ToolBoxException(Throwable throwable, String messageTemplate, Object... params) {
super(StrKit.format(messageTemplate, params), throwable);
}
}
package com.stylefeng.guns.common.node;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.stylefeng.guns.core.util.ToolUtil;
/**
* @Description 菜单的节点
* @author fengshuonan
* @date 2016年12月6日 上午11:34:17
*/
public class MenuNode {
/**
* 节点id
*/
private Integer id;
/**
* 父节点
*/
private Integer parentId;
/**
* 节点名称
*/
private String name;
/**
* 按钮级别
*/
private Integer levels;
/**
* 节点的url
*/
private String url;
/**
* 节点图标
*/
private String icon;
/**
* 子节点的集合
*/
private List<MenuNode> children;
/**
* 查询子节点时候的临时集合
*/
private List<MenuNode> linkedList = new ArrayList<MenuNode>();
public MenuNode() {
super();
}
public MenuNode(Integer id, Integer parentId) {
super();
this.id = id;
this.parentId = parentId;
}
public Integer getLevels() {
return levels;
}
public void setLevels(Integer levels) {
this.levels = levels;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public static MenuNode createRoot() {
return new MenuNode(0, -1);
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<MenuNode> getChildren() {
return children;
}
public void setChildren(List<MenuNode> children) {
this.children = children;
}
/**
* @Description 构建整个菜单树
* @param list
* 需要被构建的节点集合
* @author fengshuonan
*/
public void buildNodeTree(List<MenuNode> nodeList) {
for (MenuNode treeNode : nodeList) {
List<MenuNode> linkedList = treeNode.findChildNodes(nodeList, treeNode.getId());
if (linkedList.size() > 0) {
treeNode.setChildren(linkedList);
}
}
}
/**
* @Description 查询子节点的集合
* @author fengshuonan
*/
public List<MenuNode> findChildNodes(List<MenuNode> nodeList, Integer parentId) {
if (nodeList == null && parentId == null)
return null;
for (Iterator<MenuNode> iterator = nodeList.iterator(); iterator.hasNext();) {
MenuNode node = (MenuNode) iterator.next();
// 根据传入的某个父节点ID,遍历该父节点的所有子节点
if (node.getParentId() != 0 && parentId == node.getParentId()) {
recursionFn(nodeList, node, parentId);
}
}
return linkedList;
}
/**
* @Description 遍历一个节点的子节点
* @author fengshuonan
*/
public void recursionFn(List<MenuNode> nodeList, MenuNode node, Integer pId) {
List<MenuNode> childList = getChildList(nodeList, node);// 得到子节点列表
if (childList.size() > 0) {// 判断是否有子节点
if (node.getParentId() == pId) {
linkedList.add(node);
}
Iterator<MenuNode> it = childList.iterator();
while (it.hasNext()) {
MenuNode n = (MenuNode) it.next();
recursionFn(nodeList, n, pId);
}
} else {
if (node.getParentId() == pId) {
linkedList.add(node);
}
}
}
/**
* @Description 得到子节点列表
* @author fengshuonan
*/
private List<MenuNode> getChildList(List<MenuNode> list, MenuNode node) {
List<MenuNode> nodeList = new ArrayList<MenuNode>();
Iterator<MenuNode> it = list.iterator();
while (it.hasNext()) {
MenuNode n = (MenuNode) it.next();
if (n.getParentId() == node.getId()) {
nodeList.add(n);
}
}
return nodeList;
}
@Override
public String toString() {
return "MenuNode [id=" + id + ", parentId=" + parentId + ", name=" + name + ", url=" + url + ", children="
+ children + "]";
}
/**
* 清除掉按钮级别的资源
* @param nodes
* @return
* @date 2017年2月19日 下午11:04:11
*/
public static List<MenuNode> clearBtn(List<MenuNode> nodes){
ArrayList<MenuNode> noBtns = new ArrayList<MenuNode>();
for(MenuNode node : nodes){
if(node.getLevels() < 3){
noBtns.add(node);
}
}
return noBtns;
}
/**
* 清除不包含子节点的节点
* @return
* @date 2017年2月19日 下午11:18:19
*/
public static List<MenuNode> clearNoChild(List<MenuNode> nodes){
ArrayList<MenuNode> results = new ArrayList<MenuNode>();
for(MenuNode node : nodes){
if(ToolUtil.isNotEmpty(node.getChildren())){
results.add(node);
}
}
return results;
}
/**
* 构建菜单列表
* @return
* @date 2017年2月19日 下午11:18:19
*/
public static List<MenuNode> buildTitle(List<MenuNode> nodes){
List<MenuNode> clearBtn = clearBtn(nodes);
new MenuNode().buildNodeTree(clearBtn);
return clearNoChild(clearBtn);
}
}
package com.stylefeng.guns.common.node;
/**
*
* jquery ztree 插件的节点
*
* @author fengshuonan
* @date 2017年2月17日 下午8:25:14
*/
public class ZTreeNode {
private Integer id; //节点id
private Integer pId;//父节点id
private String name;//节点名称
private Boolean open;//是否打开节点
private Boolean checked;//是否被选中
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getpId() {
return pId;
}
public void setpId(Integer pId) {
this.pId = pId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getOpen() {
return open;
}
public void setOpen(Boolean open) {
this.open = open;
}
public Boolean getChecked() {
return checked;
}
public void setChecked(Boolean checked) {
this.checked = checked;
}
public static ZTreeNode createParent(){
ZTreeNode zTreeNode = new ZTreeNode();
zTreeNode.setChecked(true);
zTreeNode.setId(0);
zTreeNode.setName("顶级");
zTreeNode.setOpen(true);
zTreeNode.setpId(0);
return zTreeNode;
}
}
package com.stylefeng.guns.common.page;
/**
*
* 分页参数类(for BootStrap Table)
*
* @author fengshuonan
* @date 2017年1月21日 下午2:21:35
*/
public class PageBT {
private int limit; // 每页显示个数
private int offset; // 查询的偏移量(查询的页数 = offset/limit + 1)
private String order; // 排序方式
public PageBT() {
super();
}
public PageBT(int limit, int offset) {
super();
this.limit = limit;
this.offset = offset;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
public int getPageSize() {
return this.limit;
}
public int getPageNumber() {
return this.offset / this.limit + 1;
}
@Override
public String toString() {
return "PageBT [limit=" + limit + ", offset=" + offset + ", order=" + order + "]";
}
}
package com.stylefeng.guns.common.page;
import com.baomidou.mybatisplus.plugins.Page;
import java.util.List;
/**
*
* 分页结果的封装(for Bootstrap Table)
*
* @author fengshuonan
* @Date 2017年1月22日 下午11:06:41
*/
public class PageInfoBT<T> {
// 结果集
private List<T> rows;
// 总数
private long total;
public PageInfoBT(Page<T> page) {
this.rows = page.getRecords();
this.total = page.getTotal();
}
public List<T> getRows() {
return rows;
}
public void setRows(List<T> rows) {
this.rows = rows;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
}
package com.stylefeng.guns.common.warpper;
import java.util.List;
import java.util.Map;
/**
* 控制器查询结果的包装类基类
*
* @author fengshuonan
* @date 2017年2月13日 下午10:49:36
*/
public abstract class BaseControllerWarpper {
public Object obj = null;
public BaseControllerWarpper(Object obj) {
this.obj = obj;
}
@SuppressWarnings("unchecked")
public Object warp() {
if (this.obj instanceof List) {
List<Map<String, Object>> list = (List<Map<String, Object>>) this.obj;
for (Map<String, Object> map : list) {
warpTheMap(map);
}
return list;
} else if (this.obj instanceof Map) {
Map<String, Object> map = (Map<String, Object>) this.obj;
warpTheMap(map);
return map;
} else {
return this.obj;
}
}
public abstract void warpTheMap(Map<String, Object> map);
}
package com.stylefeng.guns.core.aop;
import com.stylefeng.guns.common.controller.BaseController;
import com.stylefeng.guns.core.support.HttpKit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 本系统调用次数的统计
*/
@Aspect
@Component
public class CountAop extends BaseController {
private static Object sync = new Object();
@Pointcut(value = "@annotation(com.stylefeng.guns.common.annotion.CountStat)")
private void cutPermission() {
}
@Around("cutPermission()")
public Object around(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = HttpKit.getRequest();
Object systemCount = request.getServletContext().getAttribute("systemCount");
synchronized (sync) {
if(systemCount == null){
request.getServletContext().setAttribute("systemCount", 1);
}else{
request.getServletContext().setAttribute("systemCount", (Integer)systemCount + 1);
}
}
return point.proceed();
}
}
package com.stylefeng.guns.core.aop;
import com.stylefeng.guns.common.constant.tips.ErrorTip;
import com.stylefeng.guns.common.exception.BizExceptionEnum;
import com.stylefeng.guns.common.exception.BussinessException;
import com.stylefeng.guns.core.support.HttpKit;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.DisabledAccountException;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.naming.NoPermissionException;
/**
* 全局的的异常拦截器(拦截所有的控制器)(带有@RequestMapping注解的方法上都会拦截)
*
* @author fengshuonan
* @date 2016年11月12日 下午3:19:56
*/
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger log = Logger.getLogger(this.getClass());
/**
* 拦截业务异常
*
* @author fengshuonan
*/
@ExceptionHandler(BussinessException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ErrorTip notFount(BussinessException e) {
HttpKit.getRequest().setAttribute("tip", e.getMessage());
return new ErrorTip(e.getCode(), e.getMessage());
}
/**
* 拦截未知的运行时异常
*
* @author fengshuonan
*/
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ErrorTip notFount(RuntimeException e) {
log.error("服务器异常:", e);
HttpKit.getRequest().setAttribute("tip", "服务器未知运行时异常");
return new ErrorTip(BizExceptionEnum.SERVER_ERROR);
}
/**
* 拦截未知的运行时异常
*
* @author fengshuonan
*/
@ExceptionHandler(AuthenticationException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public String unAuth(AuthenticationException e) {
log.error("用户未登陆:", e);
return "/login.html";
}
/**
* 账号被冻结
*
* @author fengshuonan
*/
@ExceptionHandler(DisabledAccountException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public String accountLocked(DisabledAccountException e, Model model) {
model.addAttribute("tips", "账号被冻结");
return "/login.html";
}
/**
* 账号密码错误
*
* @author fengshuonan
*/
@ExceptionHandler(CredentialsException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public String credentials(CredentialsException e, Model model) {
model.addAttribute("tips", "账号密码错误");
return "/login.html";
}
/**
* 无权访问该资源
*
* @author fengshuonan
*/
@ExceptionHandler(NoPermissionException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ResponseBody
public ErrorTip credentials(NoPermissionException e, Model model) {
HttpKit.getRequest().setAttribute("tip", "权限异常");
return new ErrorTip(BizExceptionEnum.NO_PERMITION);
}
}
package com.stylefeng.guns.core.aop;
import com.stylefeng.guns.core.util.DateUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @Description 日志记录
* @author fengshuonan
* @date 2016年12月6日 下午8:48:30
*/
@Aspect
@Component
public class LogAop {
private Logger log = Logger.getLogger(this.getClass());
@Pointcut("execution(* com.stylefeng.guns.*..service.*.*(..))")
public void cutService() {
}
@Around("cutService()")
public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
//获取拦截的方法名
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
String methodName = method.getName();
//如果当前用户未登录,不做日志
// ShiroUser user = ShiroKit.getUser();
// if(null == user){
// return point.proceed();
// }
//获取拦截方法的参数
String className = point.getTarget().getClass().getName();
Object[] params = point.getArgs();
StringBuilder sb = new StringBuilder();
for(Object param : params){
sb.append(param);
sb.append(" & ");
}
String msg = ToolUtil.format("[时间]:{} [类名]:{} [方法]:{} [参数]:{}", DateUtil.getTime(), className, methodName, sb.toString());
// LogFactory.me().doLog("例如:新增",msg,true);
log.info(msg);
return point.proceed();
}
}
\ No newline at end of file
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.aop;
import com.stylefeng.guns.common.annotion.Permission;
import com.stylefeng.guns.core.shiro.check.PermissionCheckManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.naming.NoPermissionException;
import java.lang.reflect.Method;
/**
* AOP 权限自定义检查
*/
@Aspect
@Component
public class PermissionAop {
@Pointcut(value = "@annotation(com.stylefeng.guns.common.annotion.Permission)")
private void cutPermission() {
}
@Around("cutPermission()")
public Object doPermission(ProceedingJoinPoint point) throws Throwable {
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
Permission permission = method.getAnnotation(Permission.class);
Object[] permissions = permission.value();
if (permissions == null || permissions.length == 0) {
//检查全体角色
boolean result = PermissionCheckManager.checkAll();
if (result) {
return point.proceed();
} else {
throw new NoPermissionException();
}
} else {
//检查指定角色
boolean result = PermissionCheckManager.check(permissions);
if (result) {
return point.proceed();
} else {
throw new NoPermissionException();
}
}
}
}
package com.stylefeng.guns.core.beetl;
public class Feng {
public Integer parseInt(Double value){
if(value != null){
return value.intValue();
}else{
return 0;
}
}
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.beetl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.beetl.core.GroupTemplate;
import com.stylefeng.guns.core.shiro.ShiroUser;
public class ShiroExt {
private static final String NAMES_DELIMETER = ",";
/**
* 获取当前 Subject
*
* @return Subject
*/
protected static Subject getSubject() {
return SecurityUtils.getSubject();
}
/**
* 获取封装的 ShiroUser
*
* @return ShiroUser
*/
public ShiroUser getUser() {
if (isGuest()) {
return null;
} else {
return (ShiroUser) getSubject().getPrincipals().getPrimaryPrincipal();
}
}
/**
* 验证当前用户是否属于该角色?,使用时与lacksRole 搭配使用
*
* @param roleName 角色名
* @return 属于该角色:true,否则false
*/
public boolean hasRole(String roleName) {
return getSubject() != null && roleName != null
&& roleName.length() > 0 && getSubject().hasRole(roleName);
}
/**
* 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。
*
* @param roleName 角色名
* @return 不属于该角色:true,否则false
*/
public boolean lacksRole(String roleName) {
return !hasRole(roleName);
}
/**
* 验证当前用户是否属于以下任意一个角色。
*
* @param roleNames 角色列表
* @return 属于:true,否则false
*/
public boolean hasAnyRoles(String roleNames) {
boolean hasAnyRole = false;
Subject subject = getSubject();
if (subject != null && roleNames != null && roleNames.length() > 0) {
for (String role : roleNames.split(NAMES_DELIMETER)) {
if (subject.hasRole(role.trim())) {
hasAnyRole = true;
break;
}
}
}
return hasAnyRole;
}
/**
* 验证当前用户是否属于以下所有角色。
*
* @param roleNames 角色列表
* @return 属于:true,否则false
*/
public boolean hasAllRoles(String roleNames) {
boolean hasAllRole = true;
Subject subject = getSubject();
if (subject != null && roleNames != null && roleNames.length() > 0) {
for (String role : roleNames.split(NAMES_DELIMETER)) {
if (!subject.hasRole(role.trim())) {
hasAllRole = false;
break;
}
}
}
return hasAllRole;
}
/**
* 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用
*
* @param permission 权限名
* @return 拥有权限:true,否则false
*/
public boolean hasPermission(String permission) {
return getSubject() != null && permission != null
&& permission.length() > 0
&& getSubject().isPermitted(permission);
}
/**
* 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。
*
* @param permission 权限名
* @return 拥有权限:true,否则false
*/
public boolean lacksPermission(String permission) {
return !hasPermission(permission);
}
/**
* 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。与notAuthenticated搭配使用
*
* @return 通过身份验证:true,否则false
*/
public boolean authenticated() {
return getSubject() != null && getSubject().isAuthenticated();
}
/**
* 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。。
*
* @return 没有通过身份验证:true,否则false
*/
public boolean notAuthenticated() {
return !authenticated();
}
/**
* 认证通过或已记住的用户。与guset搭配使用。
*
* @return 用户:true,否则 false
*/
public boolean isUser() {
return getSubject() != null && getSubject().getPrincipal() != null;
}
/**
* 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。用user搭配使用
*
* @return 访客:true,否则false
*/
public boolean isGuest() {
return !isUser();
}
/**
* 输出当前用户信息,通常为登录帐号信息。
*
* @return 当前用户信息
*/
public String principal() {
if (getSubject() != null) {
Object principal = getSubject().getPrincipal();
return principal.toString();
}
return "";
}
public static void main(String[] args) {
GroupTemplate gt = new GroupTemplate();
gt.registerFunctionPackage("shiro", new ShiroExt());
}
}
package com.stylefeng.guns.core.db;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.core.util.SpringContextHolder;
import java.util.HashMap;
import java.util.List;
/**
* <p>
* 便捷数据库操作类
* <p>
*
* <p>
* 本类的两种情景:<br>
* <br>
* 1.现有Mapper不满足简单业务的查询!<br>
* Db.create(UserLoginMapper.class).selectByPhone("18200001111");<br>
* <br>
* 2.单纯想创建现有的Mapper<br>
* Db.getMapper(UserLoginMapper.class).selectById("14779707158513204");<br>
*
* @author fengshuonan
* @date 2017年2月22日 下午8:07:17
*/
@SuppressWarnings("all")
public class Db<T> {
/**
* 每个Db类,包装一个Mapper接口,这个clazz就是接口的类类型,例如UserMapper.class
*/
private Class<T> clazz;
/**
* Mapper的父类接口
*/
private BaseMapper<?> baseMapper;
/**
* 私有构造方法,不允许自己创建
*/
private Db(Class clazz) {
this.clazz = clazz;
this.baseMapper = (BaseMapper<?>) SpringContextHolder.getBean(clazz);
}
/**
* <p>
* 创建包含指定mapper的Db工具类,使用本类的第一种用法
*
* @param clazz mapper的类类型
* @date 2017年2月22日 下午10:09:31
*/
public static <T> Db<T> create(Class<T> clazz) {
return new Db<T>(clazz);
}
/**
* <p>
* 获取一个mapper的快捷方法
*
* @param clazz mapper类的类对象
* @date 2017年2月22日 下午10:31:35
*/
public BaseMapper<?> getMapper() {
return this.baseMapper;
}
/**
* <p>
* 获取一个mapper的快捷方法
*
* @param clazz mapper类的类对象
* @date 2017年2月22日 下午10:31:35
*/
public static <T> T getMapper(Class<T> clazz) {
return SpringContextHolder.getBean(clazz);
}
/**
* 通过一个条件获取数据库中的一条记录(会返回null)
*
* @date 2017年2月22日 下午10:45:51
*/
public <E> E selectOneByCon(String condition, Object value) {
List<?> results = selectOneByConList(condition, value);
if (results != null && results.size() > 0) {
return (E) results.get(0);
} else {
return null;
}
}
/**
* 通过一个条件获取一堆记录(会返回null)
*
* @date 2017年2月22日 下午10:45:51
*/
public <E> List<E> selectOneByConList(String condition, Object value) {
HashMap<String, Object> conditionMap = new HashMap<String, Object>();
conditionMap.put(condition, value);
List<E> results = (List<E>) this.baseMapper.selectByMap(conditionMap);
if (results == null || results.size() == 0) {
return null;
} else {
return results;
}
}
}
package com.stylefeng.guns.core.intercept;
import com.stylefeng.guns.common.controller.BaseController;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import com.stylefeng.guns.core.util.HttpSessionHolder;
/**
* 静态调用session的拦截器
*
* @author fengshuonan
* @date 2016年11月13日 下午10:15:42
*/
@Aspect
public class SessionInterceptor extends BaseController {
@Pointcut("execution(* com.stylefeng.guns.*..controller.*.*(..))")
public void cutService() {
}
@Around("cutService()")
public Object sessionKit(ProceedingJoinPoint point) throws Throwable {
HttpSessionHolder.put(super.getHttpServletRequest().getSession());
try {
return point.proceed();
} finally {
HttpSessionHolder.remove();
}
}
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.HashMap;
import java.util.Map;
public class ConfigListener implements ServletContextListener {
private static Map<String, String> conf = new HashMap<String, String>();
public static Map<String, String> getConf() {
return conf;
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
conf.clear();
}
@Override
public void contextInitialized(ServletContextEvent evt) {
ServletContext sc = evt.getServletContext();
// 项目路径
conf.put("realPath", sc.getRealPath("/").replaceFirst("/", ""));
conf.put("contextPath", sc.getContextPath());
}
}
package com.stylefeng.guns.core.log;
/**
* 日志记录的接口
*
* @author fengshuonan
* @date 2016年12月6日 下午9:17:23
*/
public interface ILog {
/**
* @Description 日志记录
* @author fengshuonan
*/
void doLog(String logName, String msg, boolean succeed);
}
package com.stylefeng.guns.core.log;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import com.stylefeng.guns.core.util.SpringContextHolder;
/**
* 日志记录工厂
*
* @author fengshuonan
* @date 2016年12月6日 下午9:18:27
*/
@Component
@DependsOn("springContextHolder")
public class LogFactory implements ILog {
private LogFactory() {
}
public static ILog me() {
return SpringContextHolder.getBean(ILog.class);
}
@Override
public void doLog(String logName, String msg, boolean succeed) {
//添加到数据库
// ShiroUser user = ShiroKit.getUser();
// if (null == user) {
// return true;
// }
// try {
// OperationLog log = new OperationLog();
// log.setMethod(msg);
// log.setCreatetime(new Date());
// log.setSucceed((succeed)?"1":"0");
// log.setUserid(Func.toStr(user.getId()));
// log.setLogname(logName);
// boolean temp = Blade.create(OperationLog.class).save(log);
// return temp;
// } catch (Exception ex) {
// return false;
// }
}
}
package com.stylefeng.guns.core.shiro;
import com.stylefeng.guns.core.shiro.factory.IShiro;
import com.stylefeng.guns.core.shiro.factory.ShiroFactroy;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.persistence.model.User;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ShiroDbRealm extends AuthorizingRealm {
/**
* 登录认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
throws AuthenticationException {
IShiro shiroFactory = ShiroFactroy.me();
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
User user = shiroFactory.user(token.getUsername());
ShiroUser shiroUser = shiroFactory.shiroUser(user);
SimpleAuthenticationInfo info = shiroFactory.info(shiroUser, user, super.getName());
return info;
}
/**
* 权限认证
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
IShiro shiroFactory = ShiroFactroy.me();
ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
List<Integer> roleList = shiroUser.getRoleList();
Set<String> permissionSet = new HashSet<>();
Set<String> roleNameSet = new HashSet<>();
for (Integer roleId : roleList) {
List<String> permissions = shiroFactory.findPermissionsByRoleId(roleId);
if (permissions != null) {
for (String permission : permissions) {
if (ToolUtil.isNotEmpty(permission)) {
permissionSet.add(permission);
}
}
}
String roleName = shiroFactory.findRoleNameByRoleId(roleId);
roleNameSet.add(roleName);
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissionSet);
info.addRoles(roleNameSet);
return info;
}
/**
* 设置认证加密方式
*/
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
super.setCredentialsMatcher(md5CredentialsMatcher);
}
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.shiro;
import java.util.Random;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
/**
* shiro工具类
*
* @author dafei, Chill Zhuang
*/
public class ShiroKit {
private static final String NAMES_DELIMETER = ",";
/**
* 加盐参数
*/
final static String hashAlgorithmName = "MD5";
/**
* 循环次数
*/
final static int hashIterations = 1024;
/**
* shiro密码加密工具类
*
* @param 密码
* @param 密码盐
* @return
*/
public static String md5(String credentials, String saltSource) {
ByteSource salt = new Md5Hash(saltSource);
return new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations).toString();
}
/**
* 获取随机盐值
* @param length
* @return
*/
public static String getRandomSalt(int length) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
/**
* 获取当前 Subject
*
* @return Subject
*/
public static Subject getSubject() {
return SecurityUtils.getSubject();
}
/**
* 获取封装的 ShiroUser
*
* @return ShiroUser
*/
public static ShiroUser getUser() {
if (isGuest()) {
return null;
} else {
return (ShiroUser) getSubject().getPrincipals().getPrimaryPrincipal();
}
}
/**
* 从shiro获取session
*
*/
public static Session getSession() {
return getSubject().getSession();
}
/**
* 获取shiro指定的sessionKey
*
*/
@SuppressWarnings("unchecked")
public static <T> T getSessionAttr(String key) {
Session session = getSession();
return session != null ? (T) session.getAttribute(key) : null;
}
/**
* 设置shiro指定的sessionKey
*
*/
public static void setSessionAttr(String key, Object value) {
Session session = getSession();
session.setAttribute(key, value);
}
/**
* 移除shiro指定的sessionKey
*/
public static void removeSessionAttr(String key) {
Session session = getSession();
if (session != null)
session.removeAttribute(key);
}
/**
* 验证当前用户是否属于该角色?,使用时与lacksRole 搭配使用
*
* @param roleName
* 角色名
* @return 属于该角色:true,否则false
*/
public static boolean hasRole(String roleName) {
return getSubject() != null && roleName != null
&& roleName.length() > 0 && getSubject().hasRole(roleName);
}
/**
* 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。
*
* @param roleName
* 角色名
* @return 不属于该角色:true,否则false
*/
public static boolean lacksRole(String roleName) {
return !hasRole(roleName);
}
/**
* 验证当前用户是否属于以下任意一个角色。
*
* @param roleNames
* 角色列表
* @return 属于:true,否则false
*/
public static boolean hasAnyRoles(String roleNames) {
boolean hasAnyRole = false;
Subject subject = getSubject();
if (subject != null && roleNames != null && roleNames.length() > 0) {
for (String role : roleNames.split(NAMES_DELIMETER)) {
if (subject.hasRole(role.trim())) {
hasAnyRole = true;
break;
}
}
}
return hasAnyRole;
}
/**
* 验证当前用户是否属于以下所有角色。
*
* @param roleNames
* 角色列表
* @return 属于:true,否则false
*/
public static boolean hasAllRoles(String roleNames) {
boolean hasAllRole = true;
Subject subject = getSubject();
if (subject != null && roleNames != null && roleNames.length() > 0) {
for (String role : roleNames.split(NAMES_DELIMETER)) {
if (!subject.hasRole(role.trim())) {
hasAllRole = false;
break;
}
}
}
return hasAllRole;
}
/**
* 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用
*
* @param permission
* 权限名
* @return 拥有权限:true,否则false
*/
public static boolean hasPermission(String permission) {
return getSubject() != null && permission != null
&& permission.length() > 0
&& getSubject().isPermitted(permission);
}
/**
* 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。
*
* @param permission
* 权限名
* @return 拥有权限:true,否则false
*/
public static boolean lacksPermission(String permission) {
return !hasPermission(permission);
}
/**
* 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。与notAuthenticated搭配使用
*
* @return 通过身份验证:true,否则false
*/
public static boolean isAuthenticated() {
return getSubject() != null && getSubject().isAuthenticated();
}
/**
* 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。。
*
* @return 没有通过身份验证:true,否则false
*/
public static boolean notAuthenticated() {
return !isAuthenticated();
}
/**
* 认证通过或已记住的用户。与guset搭配使用。
*
* @return 用户:true,否则 false
*/
public static boolean isUser() {
return getSubject() != null && getSubject().getPrincipal() != null;
}
/**
* 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。用user搭配使用
*
* @return 访客:true,否则false
*/
public static boolean isGuest() {
return !isUser();
}
/**
* 输出当前用户信息,通常为登录帐号信息。
*
* @return 当前用户信息
*/
public static String principal() {
if (getSubject() != null) {
Object principal = getSubject().getPrincipal();
return principal.toString();
}
return "";
}
}
package com.stylefeng.guns.core.shiro;
import java.io.Serializable;
import java.util.List;
/**
* 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息
*
* @author fengshuonan
* @date 2016年12月5日 上午10:26:43
*/
public class ShiroUser implements Serializable {
private static final long serialVersionUID = 1L;
public Integer id; // 主键ID
public String account; // 账号
public String name; // 姓名
public Integer deptId; // 部门id
public List<Integer> roleList; // 角色集
public String deptName; // 部门名称
public List<String> roleNames; // 角色名称集
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public List<Integer> getRoleList() {
return roleList;
}
public void setRoleList(List<Integer> roleList) {
this.roleList = roleList;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public List<String> getRoleNames() {
return roleNames;
}
public void setRoleNames(List<String> roleNames) {
this.roleNames = roleNames;
}
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.shiro.check;
/**
* 检查用接口
*/
public interface ICheck {
/**
* 检查指定角色
* @param permissions
* @return boolean
*/
boolean check(Object[] permissions);
/**
* 检查全体角色
* @return boolean
*/
boolean checkAll();
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.shiro.check;
import com.stylefeng.guns.core.listener.ConfigListener;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.support.CollectionKit;
import com.stylefeng.guns.core.support.HttpKit;
import com.stylefeng.guns.core.util.SpringContextHolder;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
/**
* 权限自定义检查
*/
@Service
@DependsOn("springContextHolder")
@Transactional(readOnly = true)
public class PermissionCheckFactory implements ICheck {
public static ICheck me() {
return SpringContextHolder.getBean(ICheck.class);
}
@Override
public boolean check(Object[] permissions) {
ShiroUser user = ShiroKit.getUser();
if (null == user) {
return false;
}
String join = CollectionKit.join(permissions, ",");
if (ShiroKit.hasAnyRoles(join)) {
return true;
}
return false;
}
@Override
public boolean checkAll() {
HttpServletRequest request = HttpKit.getRequest();
ShiroUser user = ShiroKit.getUser();
if (null == user) {
return false;
}
String requestURI = request.getRequestURI().replace(ConfigListener.getConf().get("contextPath"), "");
String[] str = requestURI.split("/");
if (str.length > 3) {
requestURI = "/" + str[1] + "/" + str[2];
}
if (ShiroKit.hasPermission(requestURI)) {
return true;
}
return false;
}
}
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.shiro.check;
import com.stylefeng.guns.core.util.SpringContextHolder;
/**
* 权限检查工厂
*/
public class PermissionCheckManager {
private final static PermissionCheckManager me = new PermissionCheckManager();
private ICheck defaultCheckFactory = SpringContextHolder.getBean(ICheck.class);
public static PermissionCheckManager me() {
return me;
}
private PermissionCheckManager() {
}
public PermissionCheckManager(ICheck checkFactory) {
this.defaultCheckFactory = checkFactory;
}
public void setDefaultCheckFactory(ICheck defaultCheckFactory) {
this.defaultCheckFactory = defaultCheckFactory;
}
public static boolean check(Object[] permissions) {
return me.defaultCheckFactory.check(permissions);
}
public static boolean checkAll() {
return me.defaultCheckFactory.checkAll();
}
}
package com.stylefeng.guns.core.shiro.factory;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.persistence.model.User;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import java.util.List;
/**
* 定义shirorealm所需数据的接口
*
* @author fengshuonan
* @date 2016年12月5日 上午10:23:34
*/
public interface IShiro {
/**
* 根据账号获取登录用户
*
* @param account 账号
*/
public User user(String account);
/**
* 根据系统用户获取Shiro的用户
*
* @param user 系统用户
*/
public ShiroUser shiroUser(User user);
/**
* 获取权限列表通过角色id
*
* @param roleId 角色id
*/
public List<String> findPermissionsByRoleId(Integer roleId);
/**
* 根据角色id获取角色名称
*
* @param roleId 角色id
*/
public String findRoleNameByRoleId(Integer roleId);
/**
* 获取shiro的认证信息
*/
public SimpleAuthenticationInfo info(ShiroUser shiroUser, User user, String realmName);
}
package com.stylefeng.guns.core.shiro.factory;
import com.stylefeng.guns.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.common.constant.state.ManagerStatus;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.util.Convert;
import com.stylefeng.guns.core.util.SpringContextHolder;
import com.stylefeng.guns.modular.system.dao.MenuDao;
import com.stylefeng.guns.modular.system.dao.UserMgrDao;
import com.stylefeng.guns.persistence.model.User;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
@DependsOn("springContextHolder")
@Transactional(readOnly = true)
public class ShiroFactroy implements IShiro {
@Autowired
private UserMgrDao userMgrDao;
@Autowired
private MenuDao menuDao;
public static IShiro me() {
return SpringContextHolder.getBean(IShiro.class);
}
@Override
public User user(String account) {
User user = userMgrDao.getByAccount(account);
// 账号不存在
if (null == user) {
throw new CredentialsException();
}
// 账号被冻结
if (user.getStatus() != ManagerStatus.OK.getCode()) {
throw new LockedAccountException();
}
return user;
}
@Override
public ShiroUser shiroUser(User user) {
ShiroUser shiroUser = new ShiroUser();
shiroUser.setId(user.getId()); // 账号id
shiroUser.setAccount(user.getAccount());// 账号
shiroUser.setDeptId(user.getDeptid()); // 部门id
shiroUser.setDeptName(ConstantFactory.getDeptName(user.getDeptid()));// 部门名称
shiroUser.setName(user.getName()); // 用户名称
Integer[] roleArray = Convert.toIntArray(user.getRoleid());// 角色集合
List<Integer> roleList = new ArrayList<Integer>();
List<String> roleNameList = new ArrayList<String>();
for (int roleId : roleArray) {
roleList.add(roleId);
roleNameList.add(ConstantFactory.getSingleRoleName(roleId));
}
shiroUser.setRoleList(roleList);
shiroUser.setRoleNames(roleNameList);
return shiroUser;
}
@Override
public List<String> findPermissionsByRoleId(Integer roleId) {
List<String> resUrls = menuDao.getResUrlsByRoleId(roleId);
return resUrls;
}
@Override
public String findRoleNameByRoleId(Integer roleId) {
return ConstantFactory.getSingleRoleTip(roleId);
}
@Override
public SimpleAuthenticationInfo info(ShiroUser shiroUser, User user, String realmName) {
String credentials = user.getPassword();
// 密码加盐处理
String source = user.getSalt();
ByteSource credentialsSalt = new Md5Hash(source);
return new SimpleAuthenticationInfo(shiroUser, credentials, credentialsSalt, realmName);
}
}
package com.stylefeng.guns.core.support;
import java.util.HashMap;
import java.util.Map;
/**
* 基本变量类型的枚举
* @author xiaoleilu
*/
public enum BasicType {
BYTE, SHORT, INT, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, CHAR, CHARACTER, STRING;
/** 原始类型为Key,包装类型为Value,例如: int.class -> Integer.class. */
public static final Map<Class<?>, Class<?>> wrapperPrimitiveMap = new HashMap<Class<?>, Class<?>>(8);
/** 包装类型为Key,原始类型为Value,例如: Integer.class -> int.class. */
public static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<Class<?>, Class<?>>(8);
static {
wrapperPrimitiveMap.put(Boolean.class, boolean.class);
wrapperPrimitiveMap.put(Byte.class, byte.class);
wrapperPrimitiveMap.put(Character.class, char.class);
wrapperPrimitiveMap.put(Double.class, double.class);
wrapperPrimitiveMap.put(Float.class, float.class);
wrapperPrimitiveMap.put(Integer.class, int.class);
wrapperPrimitiveMap.put(Long.class, long.class);
wrapperPrimitiveMap.put(Short.class, short.class);
for (Map.Entry<Class<?>, Class<?>> entry : wrapperPrimitiveMap.entrySet()) {
primitiveWrapperMap.put(entry.getValue(), entry.getKey());
}
}
}
package com.stylefeng.guns.core.support;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import com.stylefeng.guns.common.exception.ToolBoxException;
/**
* 类工具类
* 1、扫描指定包下的所有类<br>
* 参考 http://www.oschina.net/code/snippet_234657_22722
* @author seaside_hi, xiaoleilu, chill
*
*/
public class ClassKit {
private ClassKit() {
// 静态类不可实例化
}
/**
* 是否为标准的类<br>
* 这个类必须:<br>
* 1、非接口 2、非抽象类 3、非Enum枚举 4、非数组 5、非注解 6、非原始类型(int, long等)
*
* @param clazz 类
* @return 是否为标准类
*/
public static boolean isNormalClass(Class<?> clazz) {
return null != clazz && false == clazz.isInterface() && false == isAbstract(clazz) && false == clazz.isEnum() && false == clazz.isArray() && false == clazz.isAnnotation() && false == clazz
.isSynthetic() && false == clazz.isPrimitive();
}
/**
* 是否为抽象类
*
* @param clazz 类
* @return 是否为抽象类
*/
public static boolean isAbstract(Class<?> clazz) {
return Modifier.isAbstract(clazz.getModifiers());
}
/**
* 实例化对象
*
* @param clazz 类名
* @return 对象
*/
@SuppressWarnings("unchecked")
public static <T> T newInstance(String clazz) {
if (null == clazz)
return null;
try {
return (T) Class.forName(clazz).newInstance();
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Instance class [{}] error!", clazz), e);
}
}
/**
* 实例化对象
*
* @param clazz 类
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz) {
if (null == clazz)
return null;
try {
return (T) clazz.newInstance();
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Instance class [{}] error!", clazz), e);
}
}
/**
* 实例化对象
*
* @param clazz 类
* @return 对象
*/
public static <T> T newInstance(Class<T> clazz, Object... params) {
if (null == clazz)
return null;
if (CollectionKit.isEmpty(params)) {
return newInstance(clazz);
}
try {
return clazz.getDeclaredConstructor(getClasses(params)).newInstance(params);
} catch (Exception e) {
throw new ToolBoxException(StrKit.format("Instance class [{}] error!", clazz), e);
}
}
/**
* 获得对象数组的类数组
* @param objects 对象数组
* @return 类数组
*/
public static Class<?>[] getClasses(Object... objects){
Class<?>[] classes = new Class<?>[objects.length];
for (int i = 0; i < objects.length; i++) {
classes[i] = objects[i].getClass();
}
return classes;
}
/**
* 检查目标类是否可以从原类转化<br>
* 转化包括:<br>
* 1、原类是对象,目标类型是原类型实现的接口<br>
* 2、目标类型是原类型的父类<br>
* 3、两者是原始类型或者包装类型(相互转换)
*
* @param targetType 目标类型
* @param sourceType 原类型
* @return 是否可转化
*/
public static boolean isAssignable(Class<?> targetType, Class<?> sourceType) {
if (null == targetType || null == sourceType) {
return false;
}
// 对象类型
if (targetType.isAssignableFrom(sourceType)) {
return true;
}
// 基本类型
if (targetType.isPrimitive()) {
// 原始类型
Class<?> resolvedPrimitive = BasicType.wrapperPrimitiveMap.get(sourceType);
if (resolvedPrimitive != null && targetType.equals(resolvedPrimitive)) {
return true;
}
} else {
// 包装类型
Class<?> resolvedWrapper = BasicType.primitiveWrapperMap.get(sourceType);
if (resolvedWrapper != null && targetType.isAssignableFrom(resolvedWrapper)) {
return true;
}
}
return false;
}
/**
* 设置方法为可访问
*
* @param method 方法
* @return 方法
*/
public static Method setAccessible(Method method) {
if (null != method && ClassKit.isNotPublic(method)) {
method.setAccessible(true);
}
return method;
}
/**
* 指定类是否为非public
*
* @param clazz 类
* @return 是否为非public
*/
public static boolean isNotPublic(Class<?> clazz) {
return false == isPublic(clazz);
}
/**
* 指定方法是否为非public
*
* @param method 方法
* @return 是否为非public
*/
public static boolean isNotPublic(Method method) {
return false == isPublic(method);
}
/**
* 指定类是否为Public
*
* @param clazz 类
* @return 是否为public
*/
public static boolean isPublic(Class<?> clazz) {
if (null == clazz) {
throw new NullPointerException("Class to provided is null.");
}
return Modifier.isPublic(clazz.getModifiers());
}
/**
* 指定方法是否为Public
*
* @param method 方法
* @return 是否为public
*/
public static boolean isPublic(Method method) {
if (null == method) {
throw new NullPointerException("Method to provided is null.");
}
return isPublic(method.getDeclaringClass());
}
}
\ No newline at end of file
package com.stylefeng.guns.core.support;
import java.util.Date;
/**
* 封装java.util.Date
* @author xiaoleilu
*
*/
public class DateTime extends Date{
private static final long serialVersionUID = -5395712593979185936L;
/**
* 转换JDK date为 DateTime
* @param date JDK Date
* @return DateTime
*/
public static DateTime parse(Date date) {
return new DateTime(date);
}
/**
* 当前时间
*/
public DateTime() {
super();
}
/**
* 给定日期的构造
* @param date 日期
*/
public DateTime(Date date) {
this(date.getTime());
}
/**
* 给定日期毫秒数的构造
* @param timeMillis 日期毫秒数
*/
public DateTime(long timeMillis) {
super(timeMillis);
}
@Override
public String toString() {
return DateTimeKit.formatDateTime(this);
}
public String toString(String format) {
return DateTimeKit.format(this, format);
}
/**
* @return 输出精确到毫秒的标准日期形式
*/
public String toMsStr() {
return DateTimeKit.format(this, DateTimeKit.NORM_DATETIME_MS_PATTERN);
}
/**
* @return java.util.Date
*/
public Date toDate() {
return new Date(this.getTime());
}
}
package com.stylefeng.guns.core.support;
import java.nio.charset.Charset;
/**
* 十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制,一般用数字0到9和字母A到F表示(其中:A~F即10~15)。<br>
* 例如十进制数57,在二进制写作111001,在16进制写作39。<br>
* 像java,c这样的语言为了区分十六进制和十进制数值,会在十六进制数的前面加上 0x,比如0x20是十进制的32,而不是十进制的20<br>
*
* 参考:https://my.oschina.net/xinxingegeya/blog/287476
*
* @author Looly
*
*/
public class HexKit {
/**
* 用于建立十六进制字符的输出的小写字符数组
*/
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* 用于建立十六进制字符的输出的大写字符数组
*/
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
//---------------------------------------------------------------------------------------------------- encode
/**
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @return 十六进制char[]
*/
public static char[] encodeHex(byte[] data) {
return encodeHex(data, true);
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param str 字符串
* @param charset 编码
* @return 十六进制char[]
*/
public static char[] encodeHex(String str, Charset charset) {
return encodeHex(StrKit.getBytes(str, charset), true);
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
* @return 十六进制char[]
*/
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param data byte[]
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data) {
return encodeHexStr(data, true);
}
/**
* 将字节数组转换为十六进制字符串
*
* @param data byte[]
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data, boolean toLowerCase) {
return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
//---------------------------------------------------------------------------------------------------- decode
/**
* 将十六进制字符数组转换为字符串
*
* @param hexStr 十六进制String
* @param charset 编码
* @return 字符串
*/
public static String decodeHexStr(String hexStr, Charset charset) {
if(StrKit.isEmpty(hexStr)){
return hexStr;
}
return decodeHexStr(hexStr.toCharArray(), charset);
}
/**
* 将十六进制字符数组转换为字符串
*
* @param hexData 十六进制char[]
* @param charset 编码
* @return 字符串
*/
public static String decodeHexStr(char[] hexData, Charset charset) {
return StrKit.str(decodeHex(hexData), charset);
}
/**
* 将十六进制字符数组转换为字节数组
*
* @param hexData 十六进制char[]
* @return byte[]
* @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
*/
public static byte[] decodeHex(char[] hexData) {
int len = hexData.length;
if ((len & 0x01) != 0) {
throw new RuntimeException("Odd number of characters.");
}
byte[] out = new byte[len >> 1];
// two characters form the hex value.
for (int i = 0, j = 0; j < len; i++) {
int f = toDigit(hexData[j], j) << 4;
j++;
f = f | toDigit(hexData[j], j);
j++;
out[i] = (byte) (f & 0xFF);
}
return out;
}
//---------------------------------------------------------------------------------------- Private method start
/**
* 将字节数组转换为十六进制字符串
*
* @param data byte[]
* @param toDigits 用于控制输出的char[]
* @return 十六进制String
*/
private static String encodeHexStr(byte[] data, char[] toDigits) {
return new String(encodeHex(data, toDigits));
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param data byte[]
* @param toDigits 用于控制输出的char[]
* @return 十六进制char[]
*/
private static char[] encodeHex(byte[] data, char[] toDigits) {
int l = data.length;
char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
/**
* 将十六进制字符转换成一个整数
*
* @param ch 十六进制char
* @param index 十六进制字符在字符数组中的位置
* @return 一个整数
* @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
*/
private static int toDigit(char ch, int index) {
int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);
}
return digit;
}
//---------------------------------------------------------------------------------------- Private method end
/**
* 2进制转16进制
* @param bString 2进制字符串
* @return
*/
public static String binary2Hex(String bString) {
if (bString == null || bString.equals("") || bString.length() % 8 != 0)
return null;
StringBuffer tmp = new StringBuffer();
int iTmp = 0;
for (int i = 0; i < bString.length(); i += 4) {
iTmp = 0;
for (int j = 0; j < 4; j++) {
iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
}
tmp.append(Integer.toHexString(iTmp));
}
return tmp.toString();
}
/**
* 16进制转2进制
* @param hexString
* @return
*/
public static String hex2Binary(String hexString) {
if (hexString == null || hexString.length() % 2 != 0)
return null;
String bString = "", tmp;
for (int i = 0; i < hexString.length(); i++) {
tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
bString += tmp.substring(tmp.length() - 4);
}
return bString;
}
/**
* 将二进制转换成16进制
* @param buf
* @return
*/
public static String binary2Hex(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 将16进制转换为二进制
* @param hexStr
* @return
*/
public static byte[] hex2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
/**
* Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.support;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class HttpKit {
/**
* 获取 HttpServletRequest
*/
public static HttpServletResponse getResponse() {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
return response;
}
/**
* 获取 包装防Xss Sql注入的 HttpServletRequest
* @return request
*/
public static HttpServletRequest getRequest() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
return new WafRequestWrapper(request);
}
/**
* 向指定URL发送GET方法的请求
*
* @param url 发送请求的URL
* @param param 请求参数
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, Map<String, String> param) {
String result = "";
BufferedReader in = null;
try {
String para = "";
for (String key : param.keySet()) {
para += (key + "=" + param.get(key) + "&");
}
if (para.lastIndexOf("&") > 0) {
para = para.substring(0, para.length() - 1);
}
String urlNameString = url + "?" + para;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, Map<String, String> param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
String para = "";
for (String key : param.keySet()) {
para += (key + "=" + param.get(key) + "&");
}
if (para.lastIndexOf("&") > 0) {
para = para.substring(0, para.length() - 1);
}
String urlNameString = url + "?" + para;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
}
package com.stylefeng.guns.core.support;
/**
* 一些通用的函数
*
* @author Looly
*
*/
public class ObjectKit {
/**
* 比较两个对象是否相等。<br>
* 相同的条件有两个,满足其一即可:<br>
* 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
*
* @param obj1 对象1
* @param obj2 对象2
* @return 是否相等
*/
public static boolean equals(Object obj1, Object obj2) {
return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
}
}
package com.stylefeng.guns.core.support;
/**
* 分页工具类
*
* @author xiaoleilu
*
*/
public class PageKit {
/**
* 将页数和每页条目数转换为开始位置和结束位置<br>
* 此方法用于不包括结束位置的分页方法<br>
* 例如:<br>
* 页码:1,每页10 -> [0, 10]<br>
* 页码:2,每页10 -> [10, 20]<br>
* 。。。<br>
*
* @param pageNo
* 页码(从1计数)
* @param countPerPage
* 每页条目数
* @return 第一个数为开始位置,第二个数为结束位置
*/
public static int[] transToStartEnd(int pageNo, int countPerPage) {
if (pageNo < 1) {
pageNo = 1;
}
if (countPerPage < 1) {
countPerPage = 0;
// LogKit.warn("Count per page [" + countPerPage + "] is not valid!");
}
int start = (pageNo - 1) * countPerPage;
int end = start + countPerPage;
return new int[] { start, end };
}
/**
* 根据总数计算总页数
*
* @param totalCount
* 总数
* @param numPerPage
* 每页数
* @return 总页数
*/
public static int totalPage(int totalCount, int numPerPage) {
if (numPerPage == 0) {
return 0;
}
return totalCount % numPerPage == 0 ? (totalCount / numPerPage)
: (totalCount / numPerPage + 1);
}
}
/**
* Copyright (c) 2011-2014, hubin (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.support;
import java.util.regex.Pattern;
/**
* Web防火墙工具类
* <p>
* @author hubin
* @Date 2014-5-8
*/
public class WafKit {
/**
* @Description 过滤XSS脚本内容
* @param value
* 待处理内容
* @return
*/
public static String stripXSS(String value) {
String rlt = null;
if (null != value) {
// NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
// avoid encoded attacks.
// value = ESAPI.encoder().canonicalize(value);
// Avoid null characters
rlt = value.replaceAll("", "");
// Avoid anything between script tags
Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid anything in a src='...' type of expression
/*scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");*/
// Remove any lonesome </script> tag
scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Remove any lonesome <script ...> tag
scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid eval(...) expressions
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid expression(...) expressions
scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid javascript:... expressions
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid vbscript:... expressions
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
rlt = scriptPattern.matcher(rlt).replaceAll("");
// Avoid onload= expressions
scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE
| Pattern.MULTILINE | Pattern.DOTALL);
rlt = scriptPattern.matcher(rlt).replaceAll("");
}
return rlt;
}
/**
* @Description 过滤SQL注入内容
* @param value
* 待处理内容
* @return
*/
public static String stripSqlInjection(String value) {
return (null == value) ? null : value.replaceAll("('.+--)|(--)|(%7C)", ""); //value.replaceAll("('.+--)|(--)|(\\|)|(%7C)", "");
}
/**
* @Description 过滤SQL/XSS注入内容
* @param value
* 待处理内容
* @return
*/
public static String stripSqlXSS(String value) {
return stripXSS(stripSqlInjection(value));
}
}
/**
* Copyright (c) 2011-2014, hubin (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.stylefeng.guns.core.support;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* Request请求过滤包装
* <p>
* @author hubin
* @Date 2014-5-8
*/
public class WafRequestWrapper extends HttpServletRequestWrapper {
private boolean filterXSS = true;
private boolean filterSQL = true;
public WafRequestWrapper(HttpServletRequest request, boolean filterXSS, boolean filterSQL) {
super(request);
this.filterXSS = filterXSS;
this.filterSQL = filterSQL;
}
public WafRequestWrapper(HttpServletRequest request) {
this(request, true, true);
}
/**
* @Description 数组参数过滤
* @param parameter
* 过滤参数
* @return
*/
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if ( values == null ) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for ( int i = 0 ; i < count ; i++ ) {
encodedValues[i] = filterParamString(values[i]);
}
return encodedValues;
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Map getParameterMap() {
Map<String, String[]> primary = super.getParameterMap();
Map<String, String[]> result = new HashMap<String, String[]>(primary.size());
for ( Map.Entry<String, String[]> entry : primary.entrySet() ) {
result.put(entry.getKey(), filterEntryString(entry.getValue()));
}
return result;
}
protected String[] filterEntryString(String[] rawValue) {
for ( int i = 0 ; i < rawValue.length ; i++ ) {
rawValue[i] = filterParamString(rawValue[i]);
}
return rawValue;
}
/**
* @Description 参数过滤
* @param parameter
* 过滤参数
* @return
*/
@Override
public String getParameter(String parameter) {
return filterParamString(super.getParameter(parameter));
}
/**
* @Description 请求头过滤
* @param name
* 过滤内容
* @return
*/
@Override
public String getHeader(String name) {
return filterParamString(super.getHeader(name));
}
/**
* @Description Cookie内容过滤
* @return
*/
@Override
public Cookie[] getCookies() {
Cookie[] existingCookies = super.getCookies();
if (existingCookies != null) {
for (int i = 0 ; i < existingCookies.length ; ++i) {
Cookie cookie = existingCookies[i];
cookie.setValue(filterParamString(cookie.getValue()));
}
}
return existingCookies;
}
/**
* @Description 过滤字符串内容
* @param rawValue
* 待处理内容
* @return
*/
protected String filterParamString(String rawValue) {
if (null == rawValue) {
return null;
}
String tmpStr = rawValue;
if (this.filterXSS) {
tmpStr = WafKit.stripXSS(rawValue);
}
if (this.filterSQL) {
tmpStr = WafKit.stripSqlInjection(tmpStr);
}
return tmpStr;
}
}
/**
* Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stylefeng.guns.core.util;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
private final static SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
private final static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
private final static SimpleDateFormat sdfDays = new SimpleDateFormat("yyyyMMdd");
private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private final static SimpleDateFormat sdfmsTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private final static SimpleDateFormat allTime = new SimpleDateFormat("yyyyMMddHHmmss");
/**
* 获取YYYY格式
*
* @return
*/
public static String getYear() {
return sdfYear.format(new Date());
}
/**
* 获取YYYY格式
*
* @return
*/
public static String getYear(Date date) {
return sdfYear.format(date);
}
/**
* 获取YYYY-MM-DD格式
*
* @return
*/
public static String getDay() {
return sdfDay.format(new Date());
}
/**
* 获取YYYY-MM-DD格式
*
* @return
*/
public static String getDay(Date date) {
return sdfDay.format(date);
}
/**
* 获取YYYYMMDD格式
*
* @return
*/
public static String getDays() {
return sdfDays.format(new Date());
}
/**
* 获取YYYYMMDD格式
*
* @return
*/
public static String getDays(Date date) {
return sdfDays.format(date);
}
/**
* 获取YYYY-MM-DD HH:mm:ss格式
*
* @return
*/
public static String getTime() {
return sdfTime.format(new Date());
}
/**
* 获取YYYY-MM-DD HH:mm:ss.SSS格式
*
* @return
*/
public static String getMsTime() {
return sdfmsTime.format(new Date());
}
/**
* 获取YYYYMMDDHHmmss格式
*
* @return
*/
public static String getAllTime() {
return allTime.format(new Date());
}
/**
* 获取YYYY-MM-DD HH:mm:ss格式
*
* @return
*/
public static String getTime(Date date) {
return sdfTime.format(date);
}
/**
* @Title: compareDate
* @Description:(日期比较,如果s>=e 返回true 否则返回false)
* @param s
* @param e
* @return boolean
* @throws
* @author luguosui
*/
public static boolean compareDate(String s, String e) {
if (parseDate(s) == null || parseDate(e) == null) {
return false;
}
return parseDate(s).getTime() >= parseDate(e).getTime();
}
/**
* 格式化日期
*
* @return
*/
public static Date parseDate(String date) {
try {
return sdfDay.parse(date);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
/**
* 格式化日期
*
* @return
*/
public static Date parseTime(String date) {
try {
return sdfTime.parse(date);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
/**
* 格式化日期
*
* @return
*/
public static Date parse(String date, String pattern) {
DateFormat fmt = new SimpleDateFormat(pattern);
try {
return fmt.parse(date);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
/**
* 格式化日期
*
* @return
*/
public static String format(Date date, String pattern) {
DateFormat fmt = new SimpleDateFormat(pattern);
return fmt.format(date);
}
/**
* 把日期转换为Timestamp
*
* @param date
* @return
*/
public static Timestamp format(Date date) {
return new java.sql.Timestamp(date.getTime());
}
/**
* 校验日期是否合法
*
* @return
*/
public static boolean isValidDate(String s) {
try {
sdfTime.parse(s);
return true;
} catch (Exception e) {
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
return false;
}
}
/**
* 校验日期是否合法
*
* @return
*/
public static boolean isValidDate(String s, String pattern) {
DateFormat fmt = new SimpleDateFormat(pattern);
try {
fmt.parse(s);
return true;
} catch (Exception e) {
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
return false;
}
}
public static int getDiffYear(String startTime, String endTime) {
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
try {
int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(
startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);
return years;
} catch (Exception e) {
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
return 0;
}
}
/**
* <li>功能描述:时间相减得到天数
*
* @param beginDateStr
* @param endDateStr
* @return long
* @author Administrator
*/
public static long getDaySub(String beginDateStr, String endDateStr) {
long day = 0;
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
"yyyy-MM-dd");
java.util.Date beginDate = null;
java.util.Date endDate = null;
try {
beginDate = format.parse(beginDateStr);
endDate = format.parse(endDateStr);
} catch (ParseException e) {
e.printStackTrace();
}
day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
// System.out.println("相隔的天数="+day);
return day;
}
/**
* 得到n天之后的日期
*
* @param days
* @return
*/
public static String getAfterDayDate(String days) {
int daysInt = Integer.parseInt(days);
Calendar canlendar = Calendar.getInstance(); // java.util包
canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
Date date = canlendar.getTime();
SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdfd.format(date);
return dateStr;
}
/**
* 得到n天之后是周几
*
* @param days
* @return
*/
public static String getAfterDayWeek(String days) {
int daysInt = Integer.parseInt(days);
Calendar canlendar = Calendar.getInstance(); // java.util包
canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
Date date = canlendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("E");
String dateStr = sdf.format(date);
return dateStr;
}
/**
* 格式化Oracle Date
* @param value
* @return
*/
// public static String buildDateValue(Object value){
// if(Func.isOracle()){
// return "to_date('"+ value +"','yyyy-mm-dd HH24:MI:SS')";
// }else{
// return Func.toStr(value);
// }
// }
public static void main(String[] args) {
System.out.println(getTime(new Date()));
System.out.println(getAfterDayWeek("3"));
}
}
package com.stylefeng.guns.core.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import org.apache.log4j.Logger;
import com.stylefeng.guns.common.exception.BizExceptionEnum;
import com.stylefeng.guns.common.exception.BussinessException;
public class FileUtil {
private static Logger log = Logger.getLogger(FileUtil.class);
/**
* NIO way
*/
public static byte[] toByteArray2(String filename) {
File f = new File(filename);
if (!f.exists()) {
log.error("文件未找到!" + filename);
throw new BussinessException(BizExceptionEnum.FILE_NOT_FOUND);
}
FileChannel channel = null;
FileInputStream fs = null;
try {
fs = new FileInputStream(f);
channel = fs.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
while ((channel.read(byteBuffer)) > 0) {
// do nothing
// System.out.println("reading");
}
return byteBuffer.array();
} catch (IOException e) {
throw new BussinessException(BizExceptionEnum.FILE_READING_ERROR);
} finally {
try {
channel.close();
} catch (IOException e) {
throw new BussinessException(BizExceptionEnum.FILE_READING_ERROR);
}
try {
fs.close();
} catch (IOException e) {
throw new BussinessException(BizExceptionEnum.FILE_READING_ERROR);
}
}
}
}
\ No newline at end of file
package com.stylefeng.guns.core.util;
import javax.servlet.http.HttpSession;
/**
* 非Controller中获取当前session的工具类
*
* @author fengshuonan
* @date 2016年11月28日 上午10:24:31
*/
public class HttpSessionHolder {
private static ThreadLocal<HttpSession> tl = new ThreadLocal<HttpSession>();
public static void put(HttpSession s) {
tl.set(s);
}
public static HttpSession get() {
return tl.get();
}
public static void remove() {
tl.remove();
}
}
package com.stylefeng.guns.core.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* MD5加密类(封装jdk自带的md5加密方法)
*
* @author fengshuonan
* @date 2016年12月2日 下午4:14:22
*/
public class MD5Util {
public static String encrypt(String source) {
return encodeMd5(source.getBytes());
}
private static String encodeMd5(byte[] source) {
try {
return encodeHex(MessageDigest.getInstance("MD5").digest(source));
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
private static String encodeHex(byte[] bytes) {
StringBuffer buffer = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
if (((int) bytes[i] & 0xff) < 0x10)
buffer.append("0");
buffer.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buffer.toString();
}
public static void main(String[] args) {
System.out.println(encrypt("123456"));
}
}
package com.stylefeng.guns.core.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/**
* 数字格式化的类
*
* @author fengshuonan
* @date 2016年11月30日 下午5:58:40
*/
public class NumUtil {
/**
* @Description 保留指定位数的小数(少的位数不补零)
* @author fengshuonan
*/
public static String keepRandomPoint(Double value, int n) {
if (value == null) {
value = 0.00;
return new BigDecimal(value).setScale(n, RoundingMode.HALF_UP).toString();
} else {
return new BigDecimal(value).setScale(n, RoundingMode.HALF_UP).toString();
}
}
/**
* @Description 浮点保留两位小数(少的位数不补零)
* @author fengshuonan
*/
public static String keep2Point(double value) {
return keepRandomPoint(value, 2);
}
/**
* @Description 浮点保留1位小数(少的位数不补零)
* @author fengshuonan
*/
public static String keep1Point(double value) {
return keepRandomPoint(value, 1);
}
/**
* @Description 浮点保留任意位小数(少位补零)
* @author fengshuonan
*/
public static String keepRandomPointZero(double value, int n) {
DecimalFormat df = new DecimalFormat("#0.00");
return df.format(Double.valueOf(keepRandomPoint(value, n)));
}
/**
* @Description 浮点保留两位小数(少位补零)
* @author fengshuonan
*/
public static String keep2PointZero(double value) {
return keepRandomPointZero(value, 2);
}
/**
* @Description 获取任意小数点位的百分比表示
* @author fengshuonan
*/
public static String percentRandomPoint(double value, int n) {
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setGroupingUsed(false);
percent.setMaximumFractionDigits(n);
return percent.format(value);
}
/**
* @Description 百分比保留两位小数
* @author fengshuonan
*/
public static String percent2Point(double value) {
return percentRandomPoint(value, 2);
}
/**
* @Description 获取格式化经纬度后的小数(保留3位)
* @author fengshuonan
*/
public static String latLngPoint(double value) {
return keepRandomPoint(value, 3);
}
}
package com.stylefeng.guns.core.util;
import java.util.Random;
/***
*
* 得到中文首字母
*
* @author lxm_09
*
*/
public class PingYinUtil {
public static void main(String[] args) {
String str = "这是一个测试";
System.out.println("中文首字母:" + getPYIndexStr(str, true));
}
/**
* 返回首字母
*/
public static String getPYIndexStr(String strChinese, boolean bUpCase) {
try {
StringBuffer buffer = new StringBuffer();
byte b[] = strChinese.getBytes("GBK");// 把中文转化成byte数组
for (int i = 0; i < b.length; i++) {
if ((b[i] & 255) > 128) {
int char1 = b[i++] & 255;
char1 <<= 8;// 左移运算符用“<<”表示,是将运算符左边的对象,向左移动运算符右边指定的位数,并且在低位补零。其实,向左移n位,就相当于乘上2的n次方
int chart = char1 + (b[i] & 255);
buffer.append(getPYIndexChar((char) chart, bUpCase));
continue;
}
char c = (char) b[i];
if (!Character.isJavaIdentifierPart(c))// 确定指定字符是否可以是 Java
// 标识符中首字符以外的部分。
c = 'A';
buffer.append(c);
}
return buffer.toString();
} catch (Exception e) {
System.out.println((new StringBuilder()).append("\u53D6\u4E2D\u6587\u62FC\u97F3\u6709\u9519")
.append(e.getMessage()).toString());
}
return null;
}
/**
* 得到首字母
*/
private static char getPYIndexChar(char strChinese, boolean bUpCase) {
int charGBK = strChinese;
char result;
if (charGBK >= 45217 && charGBK <= 45252)
result = 'A';
else
if (charGBK >= 45253 && charGBK <= 45760)
result = 'B';
else
if (charGBK >= 45761 && charGBK <= 46317)
result = 'C';
else
if (charGBK >= 46318 && charGBK <= 46825)
result = 'D';
else
if (charGBK >= 46826 && charGBK <= 47009)
result = 'E';
else
if (charGBK >= 47010 && charGBK <= 47296)
result = 'F';
else
if (charGBK >= 47297 && charGBK <= 47613)
result = 'G';
else
if (charGBK >= 47614 && charGBK <= 48118)
result = 'H';
else
if (charGBK >= 48119 && charGBK <= 49061)
result = 'J';
else
if (charGBK >= 49062 && charGBK <= 49323)
result = 'K';
else
if (charGBK >= 49324 && charGBK <= 49895)
result = 'L';
else
if (charGBK >= 49896 && charGBK <= 50370)
result = 'M';
else
if (charGBK >= 50371 && charGBK <= 50613)
result = 'N';
else
if (charGBK >= 50614 && charGBK <= 50621)
result = 'O';
else
if (charGBK >= 50622 && charGBK <= 50905)
result = 'P';
else
if (charGBK >= 50906 && charGBK <= 51386)
result = 'Q';
else
if (charGBK >= 51387 && charGBK <= 51445)
result = 'R';
else
if (charGBK >= 51446 && charGBK <= 52217)
result = 'S';
else
if (charGBK >= 52218 && charGBK <= 52697)
result = 'T';
else
if (charGBK >= 52698 && charGBK <= 52979)
result = 'W';
else
if (charGBK >= 52980 && charGBK <= 53688)
result = 'X';
else
if (charGBK >= 53689 && charGBK <= 54480)
result = 'Y';
else
if (charGBK >= 54481 && charGBK <= 55289)
result = 'Z';
else
result = (char) (65 + (new Random()).nextInt(25));
if (!bUpCase)
result = Character.toLowerCase(result);
return result;
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment