質問

I am working on a Login module for a Web Application using Struts2 + Spring + Hibernate, and I want to force the users to Login if they want to navigate trough the site.

I have an LoginInterceptor

public class LoginInterceptor implements Interceptor {

public LoginInterceptor() {
}

public void destroy() {
    System.out.println("LoginInterceptor destroy() is called...");
}

public void init() {
    System.out.println("LoginInterceptor init() is called...");
}

public String intercept(ActionInvocation actionInvocation) throws Exception {

    final ActionContext context = actionInvocation.getInvocationContext();
    HttpServletRequest request = (HttpServletRequest) context.get(ServletActionContext.HTTP_REQUEST);
    HttpSession session = request.getSession(true);

    //Code

    try {

        Users userObj = (Users) session.getAttribute("userObj");

        if (userObj == null) {
            System.out.println("if from LoginInterceptor");
            return "noLogin";
        }

    } catch (Exception e) {
        Logger.getLogger(LoginInterceptor.class.getName()).log(Level.INFO, "message", e);
    }

    //Invoke action
    String result = actionInvocation.invoke();

    return result;
}
}

My struts.xml

 <interceptors>

        <interceptor name="myLocale" class="com.deveto.struts.interceptors.LocaleInterceptor"/>
        <interceptor name="login" class="com.deveto.struts.interceptors.LoginInterceptor"/>
        <interceptor name="access" class="com.deveto.struts.interceptors.AccessInterceptor"/>

        <interceptor-stack name="defaultStack">
            <interceptor-ref name="myLocale"/>
            <interceptor-ref name="login"/>
            <interceptor-ref name="exception"/>
            <interceptor-ref name="alias"/>
            <interceptor-ref name="prepare"/>
            <interceptor-ref name="i18n"/>
            <interceptor-ref name="chain"/>
            <interceptor-ref name="debugging"/>
            <interceptor-ref name="profiling"/>
            <interceptor-ref name="fileUpload"/>
            <interceptor-ref name="checkbox"/>
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*</param>
            </interceptor-ref>
            <interceptor-ref name="conversionError"/>
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
            <interceptor-ref name="workflow">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
        </interceptor-stack>
    </interceptors>

    <default-interceptor-ref name="defaultStack"/>

    <global-results>
        <result name="noLogin" type="redirectAction">show-login</result>
        <result name="noAccess" type="redirectAction">access-required</result>
    </global-results>

    <action
        name="show-login"
        class="com.deveto.struts.actions.UsersAction" >
        <interceptor-ref name="defaultStack"/>
        <result name="success" type="tiles">tiles.login</result>
    </action>

But when I run the project, I have an Overflow exception, in Stack trace I have nothing, but Mozilla tells me that:

      The page isn't redirecting properly  

      Firefox has detected that the server is redirecting the request for this address in a way that will never complete.

and

  System.out.println("if from LoginInterceptor");

is repeated several times. I don't understand why, but I have more Interceptors, and other works good besides of this.

役に立ちましたか?

解決

When your LoginInterceptor returns its noLogin result it redirects and this gets again intercepted by LoginInterceptor which turns it into an endless redirect loop.

So you have to exclude your show-login from being intercepted by your LoginInterceptor, e.g.

Define two interceptor stacks, and set the one with LoginInterceptor as default:

<interceptor-stack name="defaultStack">
  ... same as in your question ...
</interceptor-stack>

<interceptor-stack name="noLoginStack">
  ... same as in your question but *without* the LoginInterceptor ...
</interceptor-stack>

<default-interceptor-ref name="defaultStack"/>

And then for the show-login action only, use the noLoginStack:

<action name="show-login"
    ... >
    <interceptor-ref name="noLoginStack"/>
    ...
</action>

他のヒント

Why don't you just use Spring Security to do that ? It's very simple to configure and it works perfectly with Struts2. Just start from there : http://static.springsource.org/spring-security/site/tutorial.html or there : http://www.mularien.com/blog/2008/07/07/5-minute-guide-to-spring-security/

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top