简体   繁体   中英

Struts2/Spring - execute is not being called even after passing validate

I'm having trouble with my setup, my login has passed the validation but execute function is not being called

LoginAction.java :

@Override
public String execute() throws Exception {

    System.out.println("5");
    String username = blogUser.getUsername();
    String password = blogUser.getPassword();
    blogUser = blogUserService.getUserByLogin(username, password);
    System.out.println("6");
    sessionMap.put(Constants.SESSION_USERNAME, blogUser.getUsername());
    System.out.println("7");
    sessionMap.put(Constants.SESSION_USERID, blogUser.getUserId());
    System.out.println("return:success");
    return SUCCESS;
}

@Override
public void validate() {
    System.out.println("1");
    String username = blogUser.getUsername();
    String password = blogUser.getPassword();
    System.out.println("username:"+username + ", password:"+password);
    if (username == null & password == null) {
        System.out.println("22");
        addFieldError("blogUser.username","");
    } else if (username == null || password == null) {
        System.out.println("2");
        addFieldError("blogUser.username","Invalid Login");
    } else if (!blogUserService.checkLogin(username, password)) {
        System.out.println("3");
        addFieldError("blogUser.username","Invalid Login");
    }
    System.out.println("4");
}

public String postLogin() throws Exception {
    System.out.println("77");
    return LOGIN;
}

struts.xml :

    <action name="login" class="loginActionBean" >
        <result name="input" type="tiles">/login.tiles</result>
        <result name="none" type="tiles">/login.tiles</result>
        <result name="login" type="tiles">/login.tiles</result>
        <result name="success" type="redirectAction">postPreviewAction</result>
        <result name="error" type="tiles">/login.tiles</result>
    </action>
    
    <action name="doLogin" class="loginActionBean" method="postLogin">
        <result name="login" type="tiles">/login.tiles</result>
        <result name="input" type="redirectAction">login</result>
    </action>

login.jsp :

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<div>
    <h2>Users Login</h2>
    <s:form action="login" method="post">
        <s:textfield label="Username" name="blogUser.username" />
        <s:password label="Password" name="blogUser.password" />
        <s:submit value="Login" />
    </s:form>
</div>

I can see only "4" being printed (meaning it passed the validation) but that's it, it doesn't go to "5"

EDIT:

added tiles.xml snippet

<definition name="/login.tiles" extends="baseLayout">
    <put-attribute name="body" value="/login.jsp" />
</definition>

From the Struts2 Spring Plugin documentation :

Normally, in struts.xml you specify the class for each Action. When using the default SpringObjectFactory , the framework will ask Spring to create the Action and wire up dependencies as specified by the default auto-wire behavior.

Meaning you don't need to create Spring beans out of your actions.

However, sometimes you might want the bean to be completely managed by Spring. This is useful, for example, if you wish to apply more complex AOP or Spring-enabled technologies, such as Acegi, to your beans. To do this, all you have to do is configure the bean in your Spring applicationContext.xml and then change the class attribute from your`Action in the struts.xml to use the bean name defined in Spring instead of the class name.

Struts2 itself creates new instance of action for each request, so actions are not singletons. If you create a Spring bean out of action then give it a proper scope (eg scope="prototype" ), because:

By default, a bean will be a singleton , unless the bean has a parent bean definition in which case it will inherit the parent's scope.

The loginActionBean example declaration:

<bean id="loginActionBean" class="some.package.LoginActionBean" scope="prototype" />

The action named doLogin (should have the proper name like showLogin ) is the action that shows the login page. It shouldn't be validated because it will always fail. You have to remove this from the action config

<result name="input" type="redirectAction">login</result>

And the action method should be excluded from validation. You can configure validation interceptor to exclude this method but another way to do it just put @SkipValidation annotation on the method.

@SkipValidation
public String showLogin() throws Exception { 
   System.out.println("77");
   return LOGIN;
}

The action named login has a few redundant results that could be removed

<result name="none" type="tiles">/login.tiles</result>
<result name="login" type="tiles">/login.tiles</result>        
<result name="error" type="tiles">/login.tiles</result>

Note: that validation by default is called on every action method from the action class unless it excluded from validation or doesn't have validation interceptor configured.

The final configuration:

<action name="login" class="loginActionBean" >
    <result name="input" type="tiles">/login.tiles</result>
    <result type="redirectAction">postPreviewAction</result>
</action>

<action name="showLogin" class="loginActionBean" method="showLogin">
    <result name="login" type="tiles">/login.tiles</result>
</action> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM