我使用Struts2框架来创建一个webapp。我有一个拦截器应该具有不同的行为,具体取决于调用的操作。例如,一个应始终允许执行某些操作的登录拦截器,但如果用户尚未登录,则应阻止其他操作。
我现在解决这个问题的方法是手动检查拦截器中动作的名称(和/或命名空间),并根据它确定我的行为。这种“硬编码”逻辑的缺点是,如果我编辑我的struts.xml文件很难维护,而且其他开发人员的情况也不明显。
我想知道这些是否可以在struts.xml文件(或其他文件?)中添加“元数据”以将某些操作“标记”为某种“类型”。例如,像这样:
struts.xml中
<action name="loginPage" types="login, user, viewpage" class="login.controller.LoginPage">
<result name="success">/login/jsp/Login.jsp</result>
</action>
然后在我的拦截器类中:
@Override
public String intercept(ActionInvocation invocation)
throws Exception
{
Set<String> actionTypes = invocation.getInvocationContext().getTypes();
if(actionTypes.contains("login")
{
doSomething();
}
else
{
doSomethingElse();
}
}
这是可能的,还是硬编码解析名称(空格)的唯一方法?
答案 0 :(得分:1)
显然你不能这样做,因为DTD不会允许你。
XY problem的另一个好例子:
XY问题是询问您尝试的解决方案而不是实际问题。
也就是说,你正试图解决问题X,并且你认为解决方案Y会起作用,但是当你遇到麻烦时,不要问X, 你问Y.
您真正需要的是定义一组免费运行的操作,以及在登录控制下运行的其他组。
为此,您可以在每个单个操作中手动包含Interceptor(在使用Convention插件时非常有用,否则会浪费时间),或者在struts.xml中逻辑配置操作。
<package>
是你的朋友:定义两个(或更多)包,一个使用默认设置运行,另一个为包的每个操作运行自定义拦截器:
<package name="unsecure-package" namespace="/unsecure" extends="struts-default">
<action name="login" class="org.foo.bar.actions.LoginAction">
...
</action>
<action name="askHelp" class="org.foo.bar.actions.AskHelpAction">
...
</action>
</package>
<package name="secure-package" namespace="/secure" extends="struts-default">
<interceptors>
<interceptor name="authInterceptor"
class="org.foo.bar.interceptor.AuthInterceptor"/>
<interceptor-stack name="securedStack">
<interceptor-ref name="authInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="securedStack"/>
<action name="write" class="org.foo.bar.actions.WriteAction">
...
</action>
<action name="delete" class="org.foo.bar.actions.DeleteAction">
...
</action>
</package>
这样每当你或其他人在struts.xml中添加一个Action时,只需要将它放在正确的包中,它就会自动运行。
尽可能保持拦截器与行动不相关;)