1

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.

Fenrir190
  • 13
  • 5
  • `struts2 doesn't send me to the login page with the updated errorMsg data` So where it sending you ? – Rookie007 Aug 11 '15 at 03:03
  • It just sends me to the login correct page(SOBookStore.jsp). I've checked the logic several times and I'm sure it works fine. The only time it went to the login page in the event of a failed attempt was when I pointed it there(essentially have both results point to the same location). – Fenrir190 Aug 11 '15 at 03:18
  • When your login attempt fails it should redirect to `SOLoginPage.jsp` if result name is `failure` right ? But its not going to that page is that your problem ? if so To where its redirecting when login attempt is failed ? – Rookie007 Aug 11 '15 at 03:27
  • Yeah. In actuality it seems that the execute method is just not being called at all. I place a println statement and changed to just return failure. Still goes to the successfully login page. Something must be up with the mapping. – Fenrir190 Aug 11 '15 at 03:44
  • Yup I'm positive that's the case. Struts2 seems to be calling the execute method in the Action interface for whatever reason. Changing the method to loginToSite creates an error saying there is no such method in the class... Funny because every example I've seen does this and none implements the Action interface. – Fenrir190 Aug 11 '15 at 03:51
  • Actually `execute` have some special treatment in Struts2 in your action mapping you dont need to specify `method="execute"` attribute, if you dont specify it will search for `execute` method and if it finds it will process your action !! – Rookie007 Aug 11 '15 at 03:53
  • let me try that then. If removing the method=execute fixes it cool. But now I'm intrigued on how to make it work with a custom method. – Fenrir190 Aug 11 '15 at 04:09
  • 1
    Are you sure the action's method is executing ? If not, please put a namespace in the package definition for `login` action. Also, the execute method doesn't handle if either `username` and `password` are null and hence a NPE must be thrown. Do you see any errors in the console ? – coding_idiot Aug 11 '15 at 04:17
  • Yeah still not working. I don't think action's execute method is being called anymore. Instead I'm trying to have it find the new method loginToSite(). I've been looking into how the namespace could be affecting it. the message that shows up says that com.azure.action.SOLoginAction.loginToSite method is not found. That's what's leading me to thinking something is up with the namespacing. In the event of a NPE it still goes to the login success page. – Fenrir190 Aug 11 '15 at 04:21
  • 1
    Finally got it working once I completly scrapped the project. No clue exactly what was causing the issue. Thanks for your help Andrea, coding_idiot, and babel – Fenrir190 Aug 12 '15 at 20:33

1 Answers1

0

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.

Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • 1
    I'll give this a try and check back. Didn't even think to check if there were any updates to struts. Also thanks for the tips on coding. Since I've not done much with it I thought about scrapping it and starting over. I opted to create a very simplistic example that does work. – Fenrir190 Aug 12 '15 at 17:51