baizhu06 2011-06-21 12:02
浏览 286
已采纳

一个用spring aop拦截struts action的问题

最近我需要在不改变原有的代码的前提下,记录到达struts action的HttpServletRequest和HttpServletResponse,我的第一想法就是用spring aop来做拦截。但是,这样做使得原来struts action无法获得struts上下文的内容信息,为了说明问题,我写了一个小原型,代码如下:

[color=red]类SimpleAction,这个类是用来封装获得HttpServletRequest和HttpServletResponse的方法的,跟本主题关系不大,可以跳过。[/color]
package action;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;

public class SimpleAction extends ActionSupport implements ServletRequestAware, ServletResponseAware ,SessionAware{
protected HttpServletRequest servletRequest;
protected HttpServletResponse servletResponse;
protected Map session;
public Map getSession() {
return session;
}
public void setSession(Map session) {
this.session = session;
}
public void setServletRequest(HttpServletRequest request)
{
this.servletRequest = request;
}
public HttpServletRequest getServletRequest()
{
return this.servletRequest;
}
public void setServletResponse(HttpServletResponse response)
{
this.servletResponse = response;
}
public HttpServletResponse getServletResponse()
{
return this.servletResponse;
}
}

类LoginAction,这个类的execute就是struts处理action调用的方法,但是奇怪的是,在这个方法中,本应得到jsp传来的值得username和password为空(把spring aop相关配置注释掉之后,username和password能正常传值)。loginService.validate()用作判断username和password是否符合,不符合以抛出异常的方式来告知调用者。在加上spring aop后,由于[color=red]username和password为空[/color],所以就一直返回结果"usernameInvalid"。
package action;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import service.LoginService;
import exception.*;

public class LoginAction extends SimpleAction {
private String username;
private String password;

private LoginService loginService;

public LoginService getLoginService()
{
    return loginService;
}
public void setLoginService(LoginService loginService)
{
    this.loginService = loginService;
}
public String getUsername()
{
    return username;
}
public void setUsername(String username)
{
    this.username = username;
}
public String getPassword()
{
    return password;
}
public void setPassword(String password)
{
    this.password = password;
}


@Override
public void validate()
{       
}

@Override
public String execute()
{
try{
this.getServletRequest().setAttribute("username", username);
this.getServletRequest().setAttribute("password", password);
System.out.println("username"+username);
System.out.println("username"+getUsername());
boolean result = loginService.validate(username, password);
}catch(UsernameException ue)
{
return "usernameInvalid";
}catch(PasswordException pe)
{
return "passwordInvalid";
}catch(Exception e)
{
e.printStackTrace();
return INPUT;
}
return SUCCESS;
}

}

下面是advice类,用来处理调用方法后的日志记录工作
package advice;
import java.io.*;
import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

public class LogActionAdvice implements
AfterReturningAdvice
{

public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object target) {
// TODO Auto-generated method stub
try
{
PropertyConfigurator.configure("after.properties");
Logger logger = Logger.getLogger(target.getClass());
logger.debug("...");
}catch(Exception e)
{
e.printStackTrace();
}

}
}

下面是login页面,这个页面的username空间对应action的username属性,所以应该不是struts没有配alias的问题,这里是login.jsp代码
<%@ page language="java" pageEncoding="GB2312"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//CN">


login2



/s:textfield
/s:password
/s:submit
/s:form

下面是配置文件,首先是struts的配置文件struts.xml:
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">



/index.jsp
/login.jsp
/usernameInvalid.jsp
/passwordInvalid.jsp


再来是spring的配置文件applicationContext.xml,红色部分是advice的配置,具体是匹配所有*Action的execute方法。
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
default-lazy-init="true" default-autowire="byName">

[color=red] aop:config

/aop:config
[/color]

<bean name="loginService" class="service.LoginService" />

<bean name="LoginAction" class="action.LoginAction">
    <property name="loginService">
        <ref bean="loginService"/>
    </property>
</bean> 

最后是web.xml的源码:
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<!-- 加载struts2核心 -->

struts2

org.apache.struts2.dispatcher.FilterDispatcher



struts2
/*

<!-- 指明spring配置文件在何处 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<!-- 加载spring配置文件applicationContext.xml -->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>   

在这个原型中出现的问题是,在LoginAction中,username和password为空,但是,[color=red]如果把它们set到 HttpServletRequest中,在页面usernameInvalid.jsp中却能够得到username和password的值。[/color]事先我查过一些资料,说用spring aop自动生成的代理无法获得struts上下文传递的变量值,但是我想不通为何把它们set到HttpServletRequest后却能够在前端页面显示出正确的值。
谢谢您的阅读和帮助!

  • 写回答

2条回答

  • wad12302 2011-06-21 20:50
    关注

    没有struts的拦截器可以是所有action都会被拦截的,



                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
    

    具体的怎么配置忘了 。反正是可以的 不用一个个来配置 就像struts2的默认的拦截器一样,你的action都被它拦截

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 matlab有关常微分方程的问题求解决
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考