Search code examples
javaspringstruts2shiro

How to show result page when integrating Struts 2 with Apache Shiro


Using:

  • struts2 2.5.10,
  • spring 4.x,
  • struts2-spring-plugin 2.5.10,
  • shiro 1.4.0,
  • shiro-spring 1.4.0.

web.xml :

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <display-name>Archetype Created Web Application</display-name>
  
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:beans.xml</param-value>
  </context-param>
  
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
  </filter>
  
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  
  <!-- shiro filter mapping has to be first -->
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>
   
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
</web-app>

beanx.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        ">
    
    <bean name="loginAction" class="example.shiro.action.LoginAction" >
         
    </bean>
    
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/login.jsp" />
        
        <property name="filterChainDefinitions">
            <value>
                /login.jsp = authc
                /logout = logout
                /* = authc
            </value>
        </property>
    </bean>
    
    <bean id="iniRealm" class="org.apache.shiro.realm.text.IniRealm">
        <property name="resourcePath" value="classpath:shiro.ini" />
    </bean>
    
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        
        <property name="realm" ref="iniRealm" />
    </bean>
    
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
</beans>

struts.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"> 

<struts>
    
    <constant name="struts.devMode" value="true" />
    
    <package name="default" extends="struts-default">
        
        <action name="list" class="loginAction" method="list">
            <result name="success">/success.jsp</result>
            <result name="error">error.jsp</result>
        </action>
        
    </package>
    
</struts>

index.jsp :

<body>
    <s:action name="list" />
</body>

login.jsp looks like:

<form name="loginform" action="" method="post">
        <table align="left" border="0" cellspacing="0" cellpadding="3">
            <tr>
                <td>Username:</td>
                <td><input type="text" name="username" maxlength="30"></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type="password" name="password" maxlength="30"></td>
            </tr>
            <tr>
                <td colspan="2" align="left"><input type="checkbox"
                    name="rememberMe"><font size="2">Remember Me</font></td>
            </tr>
            <tr>
                <td colspan="2" align="right"><input type="submit"
                    name="submit" value="Login"></td>
            </tr>
        </table>
    </form> 

LoginAction.list() :

public String list() {

        Subject currentUser = SecurityUtils.getSubject();

        if(currentUser.isAuthenticated()) {System.out.println("user : "+currentUser.getPrincipal());
            System.out.println("You are authenticated!");
        } else {
            System.out.println("Hey hacker, hands up!");
        }
        
        return "success";
    }

shiro.ini :

[users]
root=123,admin
guest=456,guest
frank=789,roleA,roleB

# role name=permission1,permission2,..,permissionN
[roles]
admin=*
roleA=lightsaber:*
roleB=winnebago:drive:eagle5

index.jsp, login.jsp, and success.jsp are placed under webapp.

What I want is : enter into LoginAction.list() need to be authenticated, if login success, then run LoginAction.list() and return "success" then show success.jsp which defined as Struts action result.

Now LoginAction.list() can be executed after login successful, but success.jsp is not displayed, browser is a blank page.

Why?


Solution

  • I found the reason : I used <s:action name="list" /> in index.jsp, however, the struts doc said if we want to see the result page with <s:action>, then we have to set its property executeResult to true, that is like <s:action name="list" executeResult="true"/>.

    In my opinion, this is a little wired, this attribute should be true by default.