我不理解下一种情况下Struts2验证的概念:
我的应用程序由两个操作组成:
- login.action
- 驱动器操作
我可以从浏览器命令行运行drive.action
,而无需在login.action
中填写用户和密码
如果用户没有在login.action
中成功填写用户和密码,我如何实现验证代码,以防止从命令行运行drive.action
?
验证概念
Struts2验证是通过XML或注释配置的。手册动作中的验证也是可能的,并且可以与XML和注释驱动的验证。
验证还取决于验证和工作流拦截器(两者都包含在默认的拦截器堆栈中)。这个验证拦截器自己进行验证并创建一个列表字段特定错误的数量。工作流拦截器检查存在验证错误:如果发现任何错误,则返回"输入";结果(默认情况下),将用户带回包含验证错误。
如果我们使用默认设置,而我们的操作没有"输入";定义了结果并且存在验证(或者,类型转换)错误,我们将收到一条错误消息,告诉我们不存在";输入";为操作定义的结果。
很简单,您可以通过验证配置文件或通过注释将验证器映射到字段。然后通过拦截器堆栈、自定义堆栈或defaultStack
显式或隐式引用validation
拦截器,将其应用于操作。
当验证开始时,它会调用验证管理器来执行实际验证并将错误保存到ValidationAware
操作中。
您的操作应该实现这个接口,或者只是在ActionSupport
已经实现的地方扩展它,以保存错误。然后workflow
拦截器检查这些错误,如果发现任何错误,则重定向到INPUT
结果,如果没有发现错误,则执行操作调用。您还可以通过实现Validateable
接口(默认情况下实现ActionSupport
)向操作添加编程验证,从而覆盖validate()
方法。
作为对基于XML的验证的补充,您还可以应用基于注释的配置。这只是服务器端验证,客户端验证通过Struts标签应用于启用浏览器的javascript,用于将验证内容呈现到被验证的页面。
所有这些概念都不适用于需要身份验证的操作(除非将身份验证拦截器应用于该操作)。如果您使用JAAS身份验证,那么您应该考虑实现PrincipalAware
的操作,或者使用roles
拦截器来限制对检查isUserInRole()
的操作的访问。如果用户没有像在struts.xml
示例中那样通过身份验证,则可以使用Action.LOGIN
结果返回到身份验证拦截器中的登录页面。
要实现这一点,您需要使用Dave Newton所说的拦截器
拦截器代码为:
package com.interceptor;
public class SessionInterceptor implements Interceptor,ServletRequestAware,SessionAware
{
HttpServletRequest request; //request object
public Map<String, Object> sessionMap;
@Override
public void setSession(Map<String, Object> arg0) {
this.sessionMap = arg0;
}
@Override
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
}
@Override
public void destroy() {
}
@Override
public void init() {
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
sessionMap=invocation.getInvocationContext().getSession();
ActionContext context=(ActionContext)invocation.getInvocationContext();
String className = invocation.getAction().getClass().getName();
String ActionName = invocation.getAction().toString();//action name which is called
//below check if session map or username is null or you logic
if(sessionMap==null || sessionMap.get("userName")==null){
return "loginError"; //this will return without calling your drive.action if user name or session is null
}else{
return invocation.invoke(); //if session is available or user name then it will run the action
}
}//end of intercept method
}//end of class
struts.xml是:
<package name="Pkg" extends="struts-default" namespace="/">
<interceptors>
<interceptor name="sessionCheck" class="com.interceptor.SessionInterceptor">
</interceptor>
<interceptor-stack name="sessionStack">
<interceptor-ref name="sessionCheck"/>
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="sessionStack"></default-interceptor-ref>
<global-results>
<result name="loginError">login.jsp</result>
</global-results>
//here all the actions which you want to apply interceptor
//rest of actions where above SessionInterceptor will be applied
...
....
.....
不要在上面的包中写第一个login.action,而是在struts.xml
中创建新的包,如:
<package name="Pkg2" extends="struts-default">
<action name="login.action" class="com.action.LogAction" method="execute">
<result name="success" type="redirect">drive</result> <!-- here action name drive is action from above package where interceptor is applied or any which you want-->
</action>
</package>
我希望这就是你想要的
这里有几个链接可以帮助你
- 会话拦截器
- 程序包配置
- 拦截器
- 拦截器堆栈示例