java使用自定义注解+SpringMVC+拦截器实现简单的用户操作日志记录

1。自定义注解

@Documented //支持JavaDoc文档注释

@Inherited // 表某个被标注的类型是被继承的

@Target(ElementType.METHOD) //表明该注解对成员方法起作用

@Retention(RetentionPolicy.RUNTIME) //在编译以后仍然起作用

public @interface logRecord {

/**

* @Description: 是否记录日志

* @return: String

* @author: fss

*/

String validate() default AccessLoggingCode.CHECK_API;

/**

* @Description: 操作类型

* @return: String

* @author: fss

*/

String operation() default AccessLoggingCode.SELECT;

/**

* @Description: 操作模块

* @return: String

* @author: fss

*/

String operationModule() default "默认操作模块";

/**

* @Description: 操作备注

* @return: String

* @author: fss

*/

String remark() default "默认备注";

/**

* @Description: 操作平台

* @return: String

* @author: fss

*/

String operationTerrace() default AccessLoggingCode.savingAPP;

}


2。controller

/**

*

* @Title: SupplierLogin 

* @Description: app端运营商登录

* @param: @param response

* @param: @param request

* @param: @return     

* @return: Map

* @author: FSS   

* @throws

*/

@ResponseBody

@DataSourceAuth(validate=DatasourceConfig.dataSourceA)

@PowerAuth(validate=RestPowerAPIcontent.NORMAL_API)

@logRecord(operation=AccessLoggingCode.LOGIN ,operationTerrace = AccessLoggingCode.operatorAPP , operationModule = "app端运营商登录" , remark =AccessLoggingCode.LOGIN)

@RequestMapping(value="/v1/Amd/OperatorLogin/login",method ={RequestMethod.POST},produces="application/json;charset=utf-8")

public Map userLoginaes(@RequestBody Map map){

return operatorMemberService.operatorLoginingApp(map);

}

3.在spring.xml配置文件来构建拦截器(xxxx包名)

 

   

 

4.创建上面配置的拦截器, 来继承HandlerInteceptorAdaptor 或者实现 HandlerInteceptor 接口.这里集成 HandlerInteceptorAdaptor



public class logRecordInterceptor extends HandlerInterceptorAdapter {

@Autowired

private UserAccessLoggingDao useraccessLoggingDao;

/**

* 在拦截器中通过ContentCachingResponseWrapper获取HttpServletResponse响应体中的数据

* @param response

* @return

* @throws IOException

* @author: fss

*/

public static Map readPostJsonData(HttpServletResponse response) throws IOException {

        if (response instanceof ContentCachingResponseWrapper) {

        /*response.setCharacterEncoding("UTF-8"); 

    response.setHeader("Content-Type", "text/html;charset=UTF-8");*/

        ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response;

            int contentLenth = ((ContentCachingResponseWrapper) response).getContentSize();

            if (contentLenth <= 0) {

                return null;

            }

            byte[] bytes = new byte[contentLenth];

            InputStream is = responseWrapper.getContentInputStream();

            for (int index = 0; index < contentLenth; index++) {

                int value = is.read();

                if (value == -1) {

//                is.reset();

                    break;

                }

                bytes[index] = (byte) value;

            }

            //responseWrapper.getContentAsByteArray();//这里是为了测试

            String data = new String(bytes);

            //System.out.println("http util .........data:" + data);

            Map map = MapUtils.stringToMap(data);

            return map;

        }

        return null;

    }

@Override

public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {

return super.preHandle(request, response, handler);

}

// \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔),

// 字符串在编译时会被转码一次,所以是 "\\b"

// \B 是单词内部逻辑间隔(连着的两个字母字符之间的逻辑上的间隔)

static String phoneReg = "\\b(ip(hone|od)|android|opera m(ob|in)i" + "|windows (phone|ce)|blackberry" + "|s(ymbian|eries60|amsung)|p(laybook|alm|rofile/midp"

+ "|laystation portable)|nokia|fennec|htc[-_]" + "|mobile|up.browser|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

static String tableReg = "\\b(ipad|tablet|(Nexus 7)|up.browser" + "|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

// 移动设备正则匹配:手机端、平板

static Pattern phonePat = Pattern.compile(phoneReg, Pattern.CASE_INSENSITIVE);

static Pattern tablePat = Pattern.compile(tableReg, Pattern.CASE_INSENSITIVE);

/**

* 获取设备名称

* @param userAgent

* @return

*/

protected String getDeviceName(String userAgent) {

if (null == userAgent) {

userAgent = "";

}

// 匹配

Matcher matcherPhone = phonePat.matcher(userAgent);

Matcher matcherTable = tablePat.matcher(userAgent);

if (matcherPhone.find()) {

return matcherPhone.group();

} else if (matcherTable.find()) {

return matcherTable.group();

} else {

return "pc";

}

}

/**

* @Description: 返回处理

* @return: String

* @author: fss

*/

@SuppressWarnings("unchecked")

public void postHandle(HttpServletRequest request,

HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

HandlerMethod hm =  (HandlerMethod) handler;

logRecord record = hm.getMethodAnnotation(logRecord.class);

if (record != null && record.validate().equals(AccessLoggingCode.CHECK_API)) {

  String operation = record.operation();//操作类型

  String businessLogic = record.operationModule();//操作模块

  String remark = record.remark();//备注

  String terrace = record.operationTerrace();//操作平台

  String url = request.getRequestURI();// 操作的URI

  String ip = CusAccessObjectUtil.getIpAddr(request);//访问ip

  String memberId="";

  String Agent = request.getHeader("User-Agent");//DEProvinceFuBao/1.89 (iPhone; iOS 12.2; Scale/3.00)

  String getDeviceName = getDeviceName(Agent);

  try {

    //取用户信息

    if(terrace.equals(AccessLoggingCode.savingAPP)||terrace.equals(AccessLoggingCode.supplierAPP)){

  String memberId1=request.getHeader("memberId");

  if(memberId1!=null&&!operation.equals(AccessLoggingCode.LOGIN)){//非登录从Header取用户信息

  memberId = memberId1;

  }else{ //从response取用户信息

  Map parametersAll = readPostJsonData(response);

  Map parameters = null;

  if(!MapUtils.mapIsAnyBlank(parametersAll, "data")){

  parameters =  (Map) parametersAll.get("data");

  if(!MapUtils.mapIsAnyBlank(parameters, "memberId")){

  memberId = parameters.get("memberId").toString();

  remark = "请求成功";

  }

  }else if(MapUtils.mapIsAnyBlank(parametersAll, "data")&&!MapUtils.mapIsAnyBlank(parametersAll, "code")&&!SuccessCodeConfigure.SUCCESS_CODE.equals(parametersAll.get("code"))){//访问失败

      String  errorMessage = "请求失败";

      if(!MapUtils.mapIsAnyBlank(parametersAll, "errorMessage")){

  errorMessage = parametersAll.get("errorMessage").toString();

  }

  remark = "errorMessage:"+errorMessage;

  }

  }

}else if(terrace.equals(AccessLoggingCode.operatorAPP)){

String cOperatorId=request.getHeader("cOperatorId");

if(cOperatorId!=null&&!operation.equals(AccessLoggingCode.LOGIN)){//非登录从Header取用户信息

memberId = cOperatorId;

}else{//从response取用户信息

  Map parametersAll = readPostJsonData(response);

  Map parameters = null;

  if(!MapUtils.mapIsAnyBlank(parametersAll, "data")){

parameters =  (Map) parametersAll.get("data");

if(operation.equals(AccessLoggingCode.LOGIN)||operation.equals(AccessLoggingCode.LOGOUT)){

if(!MapUtils.mapIsAnyBlank(parameters, "cOperatorId")){

    memberId = parameters.get("cOperatorId").toString();

}

}

  }else if(!MapUtils.mapIsAnyBlank(parametersAll, "code")&&!SuccessCodeConfigure.SUCCESS_CODE.equals(parametersAll.get("code"))){//访问失败

      String  errorMessage = "请求失败";

  if(!MapUtils.mapIsAnyBlank(parametersAll, "errorMessage")){

  errorMessage = parametersAll.get("errorMessage").toString();

  }

  remark = "errorMessage:"+errorMessage;

      }

    }

}

} catch (Exception e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

//执行日志记录(此处根据自己业务逻辑写持久化代码)


}

super.postHandle(request, response, handler, modelAndView);

}

/**

* 从request中获得参数Map,并返回可读的Map

*

* @param request

* @return

*/

@SuppressWarnings({ "unchecked", "rawtypes" })

public static Map getParameterMap(HttpServletRequest request) {

    // 参数Map

    Map properties = request.getParameterMap();

    // 返回值Map

    Map returnMap = new HashMap();

    Iterator entries = properties.entrySet().iterator();

    Map.Entry entry;

    String name = "";

    String value = "";

    while (entries.hasNext()) {

        entry = (Map.Entry) entries.next();

        name = (String) entry.getKey();

        Object valueObj = entry.getValue();

        if(null == valueObj){

            value = "";

        }else if(valueObj instanceof String[]){

            String[] values = (String[])valueObj;

            for(int i=0;i

                value = values[i] + ",";

            }

            value = value.substring(0, value.length()-1);

        }else{

            value = valueObj.toString();

        }

        returnMap.put(name, value);

    }

    return returnMap;

}

}



其实利用拦截器还可以做简单的权限控制、一些敏感词过滤、简单的数据统计

你可能感兴趣的:(java使用自定义注解+SpringMVC+拦截器实现简单的用户操作日志记录)