javajspstruts2tomcat8struts-action

Struts2 Web App Doesn't Forward to the Correct Page


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="SOIndex" extends="struts-default" namespace="/">
      <action name="index" >
            <result> /WEB-INF/jsp/SOLoginPage.jsp </result>
      </action>
   </package>
   <package name="SOLogin" extends="struts-default" >
      <action name="login" class="com.azure.action.SOLoginAction" 
              method="execute" >
            <result name="success"> /WEB-INF/jsp/SOBookStore.jsp </result>
            <result name="failure"> /WEB-INF/jsp/SOLoginPage.jsp </result>
      </action>
   </package>
</struts>

web.xml

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">
  <display-name> SO Book Store Web Application </display-name>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Action.java

package com.azure.action;

public class SOLoginAction {
    private String username;
    private String password;
    private String errorMsg;

    public String execute() throws Exception {
        String mapping = "";

        if( (this.username.equalsIgnoreCase("JE90") && this.password.equals("admin")) ) {
            mapping = "success";
            errorMsg = "";
        }
        else {
            mapping = "failure";
            errorMsg = "Incorrect username or password.\nReview credentials and try again.";
        }

        return mapping;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
}

SOLoginPage.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>SO Book Store Login Page! </title>
</head>
<body>
    <font color="red"><s:property value="errorMsg" /></font>

    <s:form action="login" method="post">
        <s:textfield name="username" label="Username" />
        <s:password name="password" label="Password" />
        <s:submit value="Login" />
    </s:form>
</body>
</html>

SOBookStore.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title> SO Book Store </title>
</head>
<body>
    <h1> Login Successful <s:property value="username" />! </h1>

</body>
</html>

Those are all the files that I'm dealing with at the moment. The issue I'm having right now is that no matter how wrong I butcher the username and password, struts2 doesn't send me to the login page with the updated errorMsg data. I've checked all over the web and no post has presented itself that even remotely puts me on the path finding out what's wrong with this application... Any help pointing in the right direction is greatly appreciated. Previously I was doing this in struts 1.3.10 but I figured it was too old to play nice with tomcat8 so I switched to 2.3.4. Am I missing something in the transition between the struts 1 and 2?

Using Struts 2.3.4 Tomcat8 Java 1.7

Update ----- So I'm having an issue where struts2 refuses to see the supposedly overridden method execute(with or without the method="xxx" being there) or any custom method I create here is the updated struts.xml

<struts>
    <constant name="struts.devMode" value="true" />
    <package name="LoginAction" namespace="/jsp" extends="struts-default">
        <action name="login" class="com.azure.action.SOlLoginAction" method="authenticate">
            <result name="loginSuccess"> /jsp/SOBookStore.jsp </result>
            <result name="loginFail"> /jsp/SOLoginPage.jsp </result>
        </action>
    </package>
</struts>

What could I possible be doing wrong now? I know this is possible as I've seen other people use their own methods instead of overridding execute. Do I need to tell struts to use a custom method? PS I just moved the jsp file outside of the WEB-INF folder. No clue why that was bugging me so much.


Solution

  • Always specify a namespace, eg

    <package name="SOLogin" extends="struts-default" namespace="auth">
    

    and

    <s:form action="login" method="post" namespace="auth">
    

    (or better, by using s:url).

    In your case, you don't even need two packages, so start with the easy, standard, working things:

    <package name="SOIndexAndLogin" extends="struts-default" namespace="/">
        <action name="index" >
            <result> /WEB-INF/jsp/SOLoginPage.jsp </result>
        </action>
        <action name="login" class="com.azure.action.SOLoginAction">
            <result name="success"> /WEB-INF/jsp/SOBookStore.jsp </result>
            <result name="failure"> /WEB-INF/jsp/SOLoginPage.jsp </result>
        </action>
    </package>
    

    and

    <s:form action="login" method="post" namespace="/">
    

    I'm pretty sure the error is related to that. If it still doesn't work, put log print everywhere, and check server logs.

    That said, consider

    1. Using addActionError() and addActionMessage() on Actions, printing them with <s:actionerror/> and <s:actionmessage/> in the JSP, instead of reinventing the wheel with your custom errorMsg. Make your actions always extend ActionSupport.

    2. migrating to 2.3.24 (instead that to 2.3.4). A LOT of things have been fixed, added, polished. Just stay up to date, for your own safety.

    3. Ensure you are running the latest Tomcat 8, not one of the first, not fully-compatible versions.