1.书写切面类
package com.zhangyue.hades.admin.log.userhandle.aop;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import com.zhangyue.hades.admin.AdminConstant;
import com.zhangyue.hades.admin.log.userhandle.annotation.UserOperatAnnotation;
import com.zhangyue.hades.admin.util.Struts2Utils;
import com.zhangyue.hades.common.CommonConstant;
import com.zhangyue.hades.core.common.USER_OPERAT_FLAG;
import com.zhangyue.hades.core.manager.log.UserOperatLogManager;
import com.zhangyue.hades.core.model.acl.User;
import com.zhangyue.hades.core.model.acl.UserRole;
import com.zhangyue.hades.core.model.log.UserOperatLog;
@Aspect //该注解标示该类为切面类
public class UserOperatAspect {
/**
* LogService
* @generated
*/
@Autowired
private UserOperatLogManager userOperatLogManagerImpl;
/*
//新增的切面
@Pointcut("execution(* com.zhangyue.hades.admin.web.controller..*.login*(..))")
public void actionAddPointcut(){
}
@After("actionAddPointcut()")
public void excuteAdd(JoinPoint joinPoint) {
System.out.println("after add");
}*/
//标注该方法体为后置通知,当目标方法执行成功后执行该方法体
@AfterReturning("within(com.zhangyue.hades.admin.web.controller..*) && @annotation(anno)")
public void addLogSuccess(JoinPoint jp, UserOperatAnnotation anno){
UserOperatLog model = constuctObj(jp,anno);
model.setIs_success(USER_OPERAT_FLAG.SUCCESS.getFlag());
userOperatLogManagerImpl.save(model);
}
//标注该方法体为异常通知,当目标方法出现异常时,执行该方法体
@AfterThrowing(pointcut="within(com.zhangyue.hades.admin.web.controller..*) && @annotation(anno)", throwing="ex")
public void addLogError(JoinPoint jp, UserOperatAnnotation anno, RuntimeException ex){
UserOperatLog model = constuctObj(jp,anno);
model.setIs_success(USER_OPERAT_FLAG.ERROR.getFlag());
model.setError_info(ex.toString());
userOperatLogManagerImpl.save(model);
}
/**
* 构建对象
* @param joinPoint
* @param anno
* @return
*/
private UserOperatLog constuctObj( JoinPoint joinPoint, UserOperatAnnotation anno){
Object[] parames = joinPoint.getArgs();
String argument = parseParames(parames);
String className = joinPoint.getTarget().getClass().toString();
className = className.substring(className.indexOf("com"));
className = className.substring(className.lastIndexOf(".")+1, className.length());
String signature = joinPoint.getSignature().toString();
String methodName = signature.substring(signature.lastIndexOf(".")+1, signature.indexOf("("));
UserOperatLog model = new UserOperatLog();
model.setDescription(anno.Desc());
model.setHandle(anno.Handle());
model.setModule(anno.Module());
HttpServletRequest httprequest = Struts2Utils.getRequest();
User user = (User) Struts2Utils.getSession().getAttribute(AdminConstant.LOGIN_USER);
String ip = getIpAddr(httprequest);//用户IP
model.setCreate_time(new Date());
model.setUser_id(user.getId());
model.setUser_name(user.getName());
List<UserRole> userRoles = user.getRoleList();
if(userRoles.size() > 0){
StringBuilder roleIds = new StringBuilder();
StringBuilder roleIdnames = new StringBuilder();
for(UserRole role:userRoles){
roleIds.append(role.getId()+",");
roleIdnames.append(role.getRole_name()+",");
}
model.setRole_ids(roleIds.toString().substring(0, roleIds.length()-1));
model.setRole_names(roleIdnames.toString().substring(0, roleIdnames.length()-1));
}
HashMap<String, String> request_form = this.getParamsMap(httprequest);
model.setRequest_params(request_form.toString());
/*
Object[] args = joinPoint.getArgs();
for(Object a : args){
if(a != null && a instanceof HttpServletRequest){
HttpServletRequest request = (HttpServletRequest)a;
System.out.println(request.getRequestedSessionId());
HttpSession session = request.getSession(true);
Object sessionFlag = session.getAttribute("TokenFlag" + className);
Object requestFlag = request.getParameter("token");
if(sessionFlag != null &&sessionFlag.equals(requestFlag)){ //验证结果一致,既为第一次提交,删除会话中存储的token,并继续执行方法。否则不做任何处理。
session.removeAttribute("TokenFlag" + className);
joinPoint.proceed();
}
}
}
*/
// ActorVO actor = ((ActorVO)ActionContext.getContext().getSession().get(Constant.SESSION_ACTOR_KEY));
model.setClass_name(className);
model.setMethod_name(methodName);
model.setArgument(argument);
model.setIp(ip);
model.setCreate_time(new Date());
return model;
}
/**
* 解析方法参数
* @param parames 方法参数
* @return 解析后的方法参数
*/
private String parseParames(Object[] parames) {
StringBuffer sb = new StringBuffer();
for(int i=0; i<parames.length; i++){
if(parames[i] instanceof Object[] || parames[i] instanceof Collection){
JSONArray json = JSONArray.fromObject(parames[i]);
if(i==parames.length-1){
sb.append(json.toString());
}else{
sb.append(json.toString() + ",");
}
}else{
JSONObject json = JSONObject.fromObject(parames[i]);
if(i==parames.length-1){
sb.append(json.toString());
}else{
sb.append(json.toString() + ",");
}
}
}
String params = sb.toString();
params = params.replaceAll("(\"\\w+\":\"\",)", "");
params = params.replaceAll("(,\"\\w+\":\"\")", "");
return params;
}
/**
* 获取请求IP[已过滤代理IP]
*
* @param request
* @return
*/
protected String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
/**
* 解析参数成map.
*
* @param req request
* @return map参数集
*/
private HashMap<String, String> getParamsMap(HttpServletRequest req) {
Map<String, String[]> originalParaMap = req.getParameterMap();
if (null == originalParaMap || originalParaMap.isEmpty()) {
return null;
}
HashMap<String, String> params = new HashMap<String, String>();
/* String ip = this.getIpAddr(req);
params.put("req_ip", ip);*/
String value = null;
for (Entry<String, String[]> entry : originalParaMap.entrySet()) {
String[] values = entry.getValue();
if (null == values || values.length == 0) {
value = StringUtils.EMPTY;
} else if (values.length == 1) {
value = values[0];
} else {
value = StringUtils.join(values, CommonConstant.SEPARATOR_COMMA);
}
params.put(entry.getKey(), value);
}
return params;
}
}
2.注解
package com.zhangyue.hades.admin.log.userhandle.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserOperatAnnotation {
String Desc() default "";
String Module() ;
String Handle() ;
}
3.配置文件配置
<aop:aspectj-autoproxy /> <!-- 这一步就完成了@AspectJ的支持,从而可以实现通过注解方式将通知编织到非公共方法中。 -->
<bean id="userHandleAspect" class="com.zhangyue.hades.admin.log.userhandle.aop.UserOperatAspect"></bean>
4.使用
/**
* 用户登录
*/
@UserOperatAnnotation(Handle="登录",Module=module)
public void login() {
String user_name = Struts2Utils.getParameter("user_name");
String user_pwd = Struts2Utils.getParameter("user_pwd");
JSONObject ajaxJson = new JSONObject();
if (StringUtils.isBlank(user_name) || StringUtils.isBlank(user_pwd)) {
ajaxJson.put("success", false);
ajaxJson.put("msg", "用户名或密码错误.");
Struts2Utils.renderJson(ajaxJson);
return;
}
User user = userManager.findUserByName(user_name);
if (user == null) {
ajaxJson.put("success", false);
ajaxJson.put("msg", "用户名或密码错误.");
Struts2Utils.renderJson(ajaxJson);
return;
}
String pwd = MD5.md5(user_pwd.trim()).toUpperCase();
if (!pwd.equalsIgnoreCase(user.getPassword())) {
ajaxJson.put("success", false);
ajaxJson.put("msg", "用户名或密码错误.");
Struts2Utils.renderJson(ajaxJson);
return;
}
ajaxJson.put("success", true);
Struts2Utils.getSession().setAttribute(AdminConstant.LOGIN_USER, user);
Struts2Utils.getSession().setAttribute(AdminConstant.VISIBLE_MENU, menuService.findVisibleMenu(user));
Struts2Utils.renderJson(ajaxJson);
}
注意:对于Structs中,一般需要增加:
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true" />
以便Structs2中优先使用Spring的装配类,就是Spring来负责类的加载,初始化。