欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Aspect基于spingmvc自定义注解实现操作记录

程序员文章站 2022-06-21 17:06:18
现在做的项目中用到了日志记录功能,整理了一下,发出来,也是做个记录:相关jar包百度云下载 1.自定义注解类 SystemControllerLog.java import java.lang.annotation.ElementType; import java.lang.annotation.R ......

  现在做的项目中用到了日志记录功能,整理了一下,发出来,也是做个记录:

  1.自定义注解类  SystemControllerLog.java

  Aspect基于spingmvc自定义注解实现操作记录
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解 拦截Controller
 * 
 * @author Administrator
 *
 */
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SystemControllerLog {
    /**
     * 描述业务操作 例:Xxx管理-执行Xxx操作
     * @return
     */
    String description() default "";
}
View Code

  2.日志处理类 SystemLogAspect.java

  Aspect基于spingmvc自定义注解实现操作记录
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import com.zw.annotation.SystemControllerLog;
import com.zw.aop.SystemLogAspect;
import com.zw.model.Logs;
import com.zw.model.User;
import com.zw.service.LogsService;
import com.zw.util.AcquireIp;
import com.zw.util.DateUtils;

/**
 * 系统日志切面类
 * */
@Aspect
@Component
public class SystemLogAspect {
private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);
    
    private static final ThreadLocal<Date> beginTimeThreadLocal =
            new NamedThreadLocal<Date>("ThreadLocal beginTime");
    
    private static final ThreadLocal<Logs> logThreadLocal = 
            new NamedThreadLocal<Logs>("ThreadLocal log");
    
    private static final ThreadLocal<User> currentUser=new NamedThreadLocal<>("ThreadLocal authUser");
    
    @Resource
    private HttpServletRequest request;
    
    @Resource(name="logsServiceImpl")
    private LogsService logsService;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    
    /**
     * Controller层切点 注解拦截
     */
    @Pointcut("@annotation(com.ht.annotation.SystemControllerLog)")
    public void controllerAspect(){}
    
    /**
     * 方法规则拦截
     */
    @Pointcut("execution(* com.ht.controller.*.*(..))")
    public void controllerPointerCut(){}
    
    /**
     * 前置通知 用于拦截Controller层记录用户的操作的开始时间
     * @param joinPoint 切点
     * @throws InterruptedException 
     */
    @Before("controllerAspect()")
    public void doBefore(JoinPoint joinPoint) throws InterruptedException{
        Date beginTime=new Date();
        beginTimeThreadLocal.set(beginTime);
        //debug模式下 显式打印开始时间用于调试
        if (logger.isDebugEnabled()){
            logger.debug("开始计时: {}  URI: {}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
                .format(beginTime), request.getRequestURI());
        }
        
        //读取session中的用户 
        HttpSession session = request.getSession();       
        
        User authUser = (User) session.getAttribute("user");
        currentUser.set(authUser);
    }
    
    /**
     * 后置通知 用于拦截Controller层记录用户的操作
     * @param joinPoint 切点
     */
    @After("controllerAspect()")
    public void doAfter(JoinPoint joinPoint) {
        User User = currentUser.get();
        //登入login操作 前置通知时用户未校验 所以session中不存在用户信息
        if(User == null){
            HttpSession session = request.getSession();       
            User = (User) session.getAttribute("user");    
            if(User==null){
                return;
            }
        }
        
        Object [] args = joinPoint.getArgs();
        System.out.println(args);
        
        String title="";
        String type="info";                          //日志类型(info:入库,error:错误)
        String remoteAddr=AcquireIp.getIP(request);//请求的IP
        String requestUri=request.getRequestURI();//请求的Uri
        String method=request.getMethod();          //请求的方法类型(post/get)
        Map<String,String[]> params=request.getParameterMap(); //请求提交的参数
        
        try {
            title=getControllerMethodDescription2(joinPoint);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        // debu模式下打印JVM信息。
        long beginTime = beginTimeThreadLocal.get().getTime();//得到线程绑定的局部变量(开始时间)  
        long endTime = System.currentTimeMillis();     //2、结束时间  
        if (logger.isDebugEnabled()){
            Object[] obj = new Object[7];
            obj[0] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(endTime);
            obj[1] = request.getRequestURI();
            obj[2] = DateUtils.formatDateTime(endTime - beginTime);
            obj[3] = Runtime.getRuntime().maxMemory()/1024/1024;
            obj[4] = Runtime.getRuntime().totalMemory()/1024/1024;
            obj[5] = Runtime.getRuntime().freeMemory()/1024/1024;
            obj[6] = (Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory())/1024/1024;
            logger.debug("计时结束:{}  URI: {}  耗时: {}   最大内存: {}m  已分配内存: {}m  已分配内存中的剩余空间: {}m  最大可用内存: {}m",obj);
        }
        
        //获取数据
        Logs log = new Logs();
        log.setTitle(title);
        log.setType(type);
        log.setRemoteAddr(remoteAddr);
        log.setRequestUri(requestUri);
        log.setMethod(method);
        log.setMapToParams(params);
        log.setUserId(String.valueOf(User.getId()));
        Date operateDate=beginTimeThreadLocal.get();
        log.setOperateDate(operateDate);
        log.setTimeout(DateUtils.formatDateTime(endTime - beginTime));
        
        //1.直接执行保存操作
        //this.logService.createSystemLog(log);

        //2.优化:异步保存日志
        //new SaveLogThread(log, logService).start();

        //3.再优化:通过线程池来执行日志保存
        threadPoolTaskExecutor.execute(new SaveLogThread(log, logsService));
        logThreadLocal.set(log);
    }
    
    /**
     *  异常通知 
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")  
    public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
        Logs logs = logThreadLocal.get();
        if(logs != null){
            logs.setType("error");
            logs.setException(e.toString());
            new UpdateLogThread(logs, logsService).start();            
        }
    }

    /**
     * 获取注解中对方法的描述信息 用于Controller层注解
     * 
     * @param joinPoint 切点
     * @return 方法描述
     */
    public static String getControllerMethodDescription2(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SystemControllerLog controllerLog = method
                .getAnnotation(SystemControllerLog.class);
        String discription = controllerLog.description();
        return discription;
    }
    
    /**
     * 保存日志线程
     * 
     * @author l
     *
     */
    private static class SaveLogThread implements Runnable {
        private Logs logs;
        private LogsService logsService;

        public SaveLogThread(Logs logs, LogsService logsService) {
            this.logs = logs;
            this.logsService = logsService;
        }

        @Override
        public void run() {
            logsService.insert(logs);
        }
    }
    
    /**
     * 日志更新线程
     * 
     * @author l
     *
     */
    private static class UpdateLogThread extends Thread {
        private Logs logs;
        private LogsService logsService;
    
        public UpdateLogThread(Logs logs, LogsService logsService) {
            super(UpdateLogThread.class.getSimpleName());
            this.logs = logs;
            this.logsService = logsService;
        }
    
        @Override
        public void run() {
            this.logsService.insert(logs);
        }
    }
}
View Code

  3.spring的xml添加

xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd

Aspect基于spingmvc自定义注解实现操作记录

  启用注解,扫描controller层

 <!-- 启动对@AspectJ注解的支持 -->  
    <aop:aspectj-autoproxy/> 

<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器  -->  
    <context:component-scan base-package="com.zw"></context:component-scan>

  配置日志

  <!-- 配置日志 -->
        <bean id ="threadPoolTaskExecutor"  class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
            <property name ="corePoolSize" value ="5" /> <!--核心线程数 -->
            <property name ="keepAliveSeconds" value ="3000" /> <!-- 某线程空闲超过这个时间,就回收该线程 -->
            <property name ="maxPoolSize" value ="10" />     <!--最大线程数 -->
            <property name ="queueCapacity" value ="1000" />  <!-- 队列大小 -->
            <property name= "rejectedExecutionHandler" >
                <!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 -->
                <!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 -->
                <!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
                <!-- DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
                <bean class = "java.util.concurrent.ThreadPoolExecutor$DiscardPolicy"   />
            </property>
        </bean>

  4.Controller中使用自定义注解

Aspect基于spingmvc自定义注解实现操作记录

  5.建立日志实体类,建立logs表(关于mapper,service那些就省略了)

  Aspect基于spingmvc自定义注解实现操作记录
import java.io.Serializable;
import java.util.Date;
import java.util.Map;

import com.zw.util.StringUtils;

/**
 * 用于记录日志的实体类
 * */
public class Logs implements Serializable{
    private static final long serialVersionUID = 1L;
    
    /**
     * 日志主键
     * */
    private Integer id;             
    /**
     * 日志类型
     * */
    private String type;        
    /**
     * 日志标题
     * */
    private String title;        
    /**
     * 请求ip地址
     * */
    private String remoteAddr;    
    /**
     * 访问路径
     * */
    private String requestUri;    
    /**
     * 请求方式
     * */
    private String method;        
    /**
     * 请求参数
     * */
    private String params;        
    /**
     * 异常
     * */
    private String exception;    
    /**
     * 日志开始时间
     * */
    private Date operateDate;    
    /**
     * 日志结束时间
     * */
    private String timeout;      
    /**
     * 用户id
     * */
    private String userId;  
    
    public Logs() {
        super();
    }
    public Logs(Integer id, String type, String title, String remoteAddr, String requestUri, String method,
            String params, String exception, Date operateDate, String timeout, String userId) {
        super();
        this.id = id;
        this.type = type;
        this.title = title;
        this.remoteAddr = remoteAddr;
        this.requestUri = requestUri;
        this.method = method;
        this.params = params;
        this.exception = exception;
        this.operateDate = operateDate;
        this.timeout = timeout;
        this.userId = userId;
    }
    @Override
    public String toString() {
        return "Logs [id=" + id + ", type=" + type + ", title=" + title + ", remoteAddr=" + remoteAddr
                + ", requestUri=" + requestUri + ", method=" + method + ", params=" + params + ", exception="
                + exception + ", operateDate=" + operateDate + ", timeout=" + timeout + ", userId=" + userId + "]";
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }


    public String getType() {
        return StringUtils.isBlank(type) ? type : type.trim();
    }
    public void setType(String type) {
        this.type = type;
    }


    public String getTitle() {
        return StringUtils.isBlank(title) ? title : title.trim();
    }
    public void setTitle(String title) {
        this.title = title;
    }


    public String getRemoteAddr() {
        return StringUtils.isBlank(remoteAddr) ? remoteAddr : remoteAddr.trim();
    }
    public void setRemoteAddr(String remoteAddr) {
        this.remoteAddr = remoteAddr;
    }


    public String getRequestUri() {
        return StringUtils.isBlank(requestUri) ? requestUri : requestUri.trim();
    }
    public void setRequestUri(String requestUri) {
        this.requestUri = requestUri;
    }


    public String getMethod() {
        return StringUtils.isBlank(method) ? method : method.trim();
    }
    public void setMethod(String method) {
        this.method = method;
    }


    public String getParams() {
        return StringUtils.isBlank(params) ? params : params.trim();
    }
    public void setParams(String params) {
        this.params = params;
    }

    /**
     * 设置请求参数
     * @param paramMap
     */
    public void setMapToParams(Map<String, String[]> paramMap) {
        if (paramMap == null){
            return;
        }
        StringBuilder params = new StringBuilder();
        for (Map.Entry<String, String[]> param : ((Map<String, String[]>)paramMap).entrySet()){
            params.append(("".equals(params.toString()) ? "" : "&") + param.getKey() + "=");
            String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : "");
            params.append(StringUtils.abbr(StringUtils.endsWithIgnoreCase(param.getKey(), "password") ? "" : paramValue, 100));
        }
        this.params = params.toString();
    }


    public String getException() {
        return StringUtils.isBlank(exception) ? exception : exception.trim();
    }
    public void setException(String exception) {
        this.exception = exception;
    }


    public Date getOperateDate() {
        return operateDate;
    }
    public void setOperateDate(Date operateDate) {
        this.operateDate = operateDate;
    }


    public String getTimeout() {
        return StringUtils.isBlank(timeout) ? timeout : timeout.trim();
    }
    public void setTimeout(String timeout) {
        this.timeout = timeout;
    }


    public String getUserId() {
        return StringUtils.isBlank(userId) ? userId : userId.trim();
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
}
View Code

  6.最后用到的工具类

 AcquireIp.java    Aspect基于spingmvc自定义注解实现操作记录
import javax.servlet.http.HttpServletRequest;

/**
 * 获取ip?
 * */
public class AcquireIp {
    public static String getIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (!checkIP(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (!checkIP(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (!checkIP(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    private static boolean checkIP(String ip) {
        if (ip == null || ip.length() == 0 || "unkown".equalsIgnoreCase(ip)
                || ip.split(".").length != 4) {
            return false;
        }
        return true;
    }
}
View Code
 DateUtils.java     Aspect基于spingmvc自定义注解实现操作记录
import java.text.ParseException;
import java.util.Date;

import org.apache.commons.lang3.time.DateFormatUtils;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 * @author ThinkGem
 * @version 2014-4-15
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    
    private static String[] parsePatterns = {
        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
        "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
        "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd)
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }
    
    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }
    
    /**
     * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }
    
    /**
     * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前时间字符串 格式(HH:mm:ss)
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前年份字符串 格式(yyyy)
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串 格式(MM)
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串 格式(dd)
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串 格式(E)星期几
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }
    
    /**
     * 日期型字符串转化为日期 格式
     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", 
     *   "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
     *   "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
     */
    public static Date parseDate(Object str) {
        if (str == null){
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = new Date().getTime()-date.getTime();
        return t/(24*60*60*1000);
    }

    /**
     * 获取过去的小时
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t = new Date().getTime()-date.getTime();
        return t/(60*60*1000);
    }
    
    /**
     * 获取过去的分钟
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = new Date().getTime()-date.getTime();
        return t/(60*1000);
    }
    
    /**
     * 转换为时间(天,时:分:秒.毫秒)
     * @param timeMillis
     * @return
     */
    public static String formatDateTime(long timeMillis){
        long day = timeMillis/(24*60*60*1000);
        long hour = (timeMillis/(60*60*1000)-day*24);
        long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
        long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
        long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
        return (day>0?day+",":"")+hour+":"+min+":"+s+"."+sss;
    }
    
    /**
     * 获取两个日期之间的天数
     * 
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }
    
    /**
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException {
//        System.out.println(formatDate(parseDate("2010/3/6")));
//        System.out.println(getDate("yyyy年MM月dd日 E"));
//        long time = new Date().getTime()-parseDate("2012-11-19").getTime();
//        System.out.println(time/(24*60*60*1000));
    }
}
View Code
 StringUtils.java   Aspect基于spingmvc自定义注解实现操作记录
import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringEscapeUtils;


/**
 * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
 * @author ThinkGem
 * @version 2013-05-22
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {
    
    private static final char SEPARATOR = '_';
    private static final String CHARSET_NAME = "UTF-8";
    
    /**
     * 转换为字节数组
     * @param str
     * @return
     */
    public static byte[] getBytes(String str){
        if (str != null){
            try {
                return str.getBytes(CHARSET_NAME);
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        }else{
            return null;
        }
    }
    
    /**
     * 转换为字节数组
     * @param str
     * @return
     */
    public static String toString(byte[] bytes){
        try {
            return new String(bytes, CHARSET_NAME);
        } catch (UnsupportedEncodingException e) {
            return EMPTY;
        }
    }
    
    /**
     * 是否包含字符串
     * @param str 验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inString(String str, String... strs){
        if (str != null){
            for (String s : strs){
                if (str.equals(trim(s))){
                    return true;
                }
            }
        }
        return false;
    }
    
    /**
     * 替换掉HTML标签方法
     */
    public static String replaceHtml(String html) {
        if (isBlank(html)){
            return "";
        }
        String regEx = "<.+?>";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(html);
        String s = m.replaceAll("");
        return s;
    }
    
    /**
     * 替换为手机识别的HTML,去掉样式及属性,保留回车。
     * @param html
     * @return
     */
    public static String replaceMobileHtml(String html){
        if (html == null){
            return "";
        }
        return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
    }
    
    /**
     * 替换为手机识别的HTML,去掉样式及属性,保留回车。
     * @param txt
     * @return
     */
    /*public static String toHtml(String txt){
        if (txt == null){
            return "";
        }
        return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", "&nbsp; &nbsp; ");
    }*/

    /**
     * 缩略字符串(不区分中英文字符)
     * @param str 目标字符串
     * @param length 截取长度
     * @return
     */
    public static String abbr(String str, int length) {
        if (str == null) {
            return "";
        }
        try {
            StringBuilder sb = new StringBuilder();
            int currentLength = 0;
            for (char c : replaceHtml(StringEscapeUtils.unescapeHtml(str)).toCharArray()) {
                currentLength += String.valueOf(c).getBytes("GBK").length;
                if (currentLength <= length - 3) {
                    sb.append(c);
                } else {
                    sb.append("...");
                    break;
                }
            }
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
    
    
    
    /**
     * 转换为Double类型
     */
    public static Double toDouble(Object val){
        if (val == null){
            return 0D;
        }
        try {
            return Double.valueOf(trim(val.toString()));
        } catch (Exception e) {
            return 0D;
        }
    }

    /**
     * 转换为Float类型
     */
    public static Float toFloat(Object val){
        return toDouble(val).floatValue();
    }

    /**
     * 转换为Long类型
     */
    public static Long toLong(Object val){
        return toDouble(val).longValue();
    }

    /**
     * 转换为Integer类型
     */
    public static Integer toInteger(Object val){
        return toLong(val).intValue();
    }
    
    /**
     * 获得i18n字符串
     */
/*    public static String getMessage(String code, Object[] args) {
        LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class);
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();  
        Locale localLocale = localLocaleResolver.resolveLocale(request);
        return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale);
    }*/
    
    /**
     * 获得用户远程地址
     */
    public static String getRemoteAddr(HttpServletRequest request){
        String remoteAddr = request.getHeader("X-Real-IP");
        if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("X-Forwarded-For");
        }else if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("Proxy-Client-IP");
        }else if (isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("WL-Proxy-Client-IP");
        }
        return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
    }

    /**
     * 驼峰命名法工具
     * @return
     *         toCamelCase("hello_world") == "helloWorld" 
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }

        s = s.toLowerCase();

        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /**
     * 驼峰命名法工具
     * @return
     *         toCamelCase("hello_world") == "helloWorld" 
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCapitalizeCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = toCamelCase(s);
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }
    
    /**
     * 驼峰命名法工具
     * @return
     *         toCamelCase("hello_world") == "helloWorld" 
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toUnderScoreCase(String s) {
        if (s == null) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            boolean nextUpperCase = true;

            if (i < (s.length() - 1)) {
                nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
            }

            if ((i > 0) && Character.isUpperCase(c)) {
                if (!upperCase || !nextUpperCase) {
                    sb.append(SEPARATOR);
                }
                upperCase = true;
            } else {
                upperCase = false;
            }

            sb.append(Character.toLowerCase(c));
        }

        return sb.toString();
    }
    
    /**
     * 驼峰转下划线 (暂不建议使用toUnderScoreCase)
     * @param camelCaseName
     * @return
     */
    public static String toUnderscoreName(String camelCaseName) {  
        StringBuilder result = new StringBuilder();  
        if (camelCaseName != null && camelCaseName.length() > 0) {  
            result.append(camelCaseName.substring(0, 1).toLowerCase());  
            for (int i = 1; i < camelCaseName.length(); i++) {  
                char ch = camelCaseName.charAt(i);  
                if (Character.isUpperCase(ch)) {  
                    result.append("_");  
                    result.append(Character.toLowerCase(ch));  
                } else {  
                    result.append(ch);  
                }  
            }  
        }  
        return result.toString();  
    }
    
    /**
     * 如果不为空,则设置值
     * @param target
     * @param source
     */
    public static void setValueIfNotBlank(String target, String source) {
        if (isNotBlank(source)){
            target = source;
        }
    }
 
    /**
     * 转换为JS获取对象值,生成三目运算返回结果
     * @param objectString 对象串
     *   例如:row.user.id
     *   返回:!row?'':!row.user?'':!row.user.id?'':row.user.id
     */
    public static String jsGetVal(String objectString){
        StringBuilder result = new StringBuilder();
        StringBuilder val = new StringBuilder();
        String[] vals = split(objectString, ".");
        for (int i=0; i<vals.length; i++){
            val.append("." + vals[i]);
            result.append("!"+(val.substring(1))+"?'':");
        }
        result.append(val.substring(1));
        return result.toString();
    }
    
    /**
     * 转换为utf-8字符串
     * @param s
     * @return
     */
    public static String toUtf8String(String s){ 
         StringBuffer sb = new StringBuffer(); 
           for (int i=0;i<s.length();i++){ 
              char c = s.charAt(i); 
              if (c >= 0 && c <= 255){
                  sb.append(c);
           }else{ 
                byte[] b; 
                 try { b = Character.toString(c).getBytes("utf-8");} 
                 catch (Exception ex) { 
                          b = new byte[0]; 
                 } 
                for (int j = 0; j < b.length; j++) { 
                 int k = b[j]; 
                  if (k < 0) k += 256; 
                  sb.append("%" + Integer.toHexString(k).toUpperCase()); 
                  } 
         } 
      } 
      return sb.toString(); 
    }
    
}
View Code

  数据库插入效果图:

Aspect基于spingmvc自定义注解实现操作记录

  

  建议使用了日志记录后,再用定时器定时清理过期日志,以免数据过多