Hi Lukasz,
I just figured out that I had bundled struts.xml in wrong place in WEB-INF/
instead of in WEB-INF/classes/. It is dispatching correctly now. My struts.xml
is mostly fine except for the duplicate result name in the same namespace. I
think Struts2 fails (silently) to dispatch in this case because it won't do
anything, no errors either.
I would love to learn to use Maven. I've tried several times in the past but
not successful.
Thanks,Joseph H.
On Tuesday, June 10, 2025 at 03:25:44 AM EDT, Lukasz Lenart
<[email protected]> wrote:
Is there a chance to expose source code of your app on Github? And I
would suggest learning how to use Maven to build the app instead of
Ant.
Cheers
Lukasz
pt., 6 cze 2025 o 18:49 Joseph Huynh <[email protected]>
napisał(a):
>
> Hello,
> I have a simple web application to learn how the controller works in Struts
> framework. The build is deployed to Tomcat 11.0.5. The application has two
> simple JSP files PgStudent.jsp (configured as the welcome page) and
> PgRegistration.jsp. Each page has two buttons to let user go back and forth
> between the two pages. It loads the welcome page PgStudent fine, but any
> request will encounter web error 404, like this one: There is no Action
> mapped for namespace [/] and action name [viewRegistration] associated with
> context path [/s2ex1], or from localhost_access log: 0:0:0:0:0:0:0:1 - -
> [06/Jun/2025:12:12:28 -0400] "POST /s2ex1/viewRegistration HTTP/1.1" 404 829.
> Please help see where I do it wrong. Namespace is specified in JSP files, but
> it always sees namespace as /. I am attaching the project file structure and
> the list of the files:
> Project Files Structure
> s2ex1 lib caffeine-3.1.8.jar freemarker-2.3.34.jar
> jakarta.servlet-api-5.0.0.jar (to compile only) ognl-3.3.5.jar
> struts2-core-7.0.3.jar xwork-core-2.3.35.jar src s2ex1
> RegistrationAction.java StudentAction.java WebContent
> jsp PgRegistration.jsp PgStudent.jsp WEB-INF
> struts.xml web.xml build.xml
> List of the 7 files
> 1. struts.xml<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC
> "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
> "https://struts.apache.org/dtds/struts-2.0.dtd"><struts> <constant
> name="struts.devMode" value="true"/> <!-- student namespace --> <package
> name="student" namespace="/student" extends="struts-default"> <action
> name="viewStudent" class="s2ex1.StudentAction" method="viewStudent">
> <result name="viewStudent">/jsp/PgStudent.jsp</result> </action>
> <action name="updateStudent" class="s2ex1.StudentAction"
> method="updateStudent"> <result
> name="viewStudent">/jsp/PgStudent.jsp</result> </action> </package>
> <!-- registration namespace --> <package name="registration"
>namespace="/registration" extends="struts-default"> <action
>name="viewRegistration" class="s2ex1.RegistrationAction"
>method="viewRegistration"> <result
>name="viewRegistration">/jsp/PgRegistration.jsp</result> </action>
> <action name="register" class="s2ex1.RegistrationAction"
>method="register"> <result
>name="viewRegistration">/jsp/PgRegistration.jsp</result> </action>
></package></struts>
> 2. web.xml<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
> https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
> version="5.0">
> <filter> <filter-name>struts2</filter-name>
><filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
> </filter>
> <filter-mapping> <filter-name>struts2</filter-name>
><url-pattern>/*</url-pattern> </filter-mapping>
> <!-- Set PgStudent.jsp as the default page --> <welcome-file-list>
> <welcome-file>jsp/PgStudent.jsp</welcome-file>
></welcome-file-list></web-app>
> 3. PgRegistration.jsp<%@ taglib prefix="s" uri="/struts-tags" %><html><head>
> <title>Registration Records</title></head><body> <h2>Registration
> Records</h2>
> <s:form namespace="/registration" action="register" method="post">
><s:submit value="Register for Class"/> </s:form>
> <s:form namespace="/student" action="viewStudent" method="post">
><s:submit value="Return to Student Section"/> </s:form></body></html>
> 4. PgStudent.jsp<%@ taglib prefix="s" uri="/struts-tags" %>
> <html><head> <title>Student Info</title></head><body> <h2>Student -
> Contact Information</h2>
> <s:form namespace="/student" action="updateStudent" method="post">
><s:submit value="Update Contact Info"/> </s:form>
> <s:form namespace="/registration" action="viewRegistration" method="post">
> <s:submit value="View Registrations"/> </s:form></body></html>
> 5. RegistrationAction.javapackage s2ex1;
> import jakarta.servlet.http.HttpServletRequest;//import
> jakarta.servlet.http.HttpSession;
> import org.apache.struts2.ActionSupport;import
> org.apache.struts2.action.ServletRequestAware;
> public class RegistrationAction extends ActionSupport implements
> ServletRequestAware { private static final long serialVersionUID =
> -4447001525367432296L; private HttpServletRequest request;
> @Override public void withServletRequest(HttpServletRequest request) {
> this.request = request; } public HttpServletRequest
>getWithServletRequest() { return this.request; } public String
>viewRegistration() { return "viewRegistration"; } public String
>register() { return "viewRegistration"; } public String
>viewStudent() { return "viewStudent"; }}
> 6. StudentAction.javapackage s2ex1;
> import jakarta.servlet.http.HttpServletRequest;//import
> jakarta.servlet.http.HttpSession;
> import org.apache.struts2.ActionSupport;import
> org.apache.struts2.action.ServletRequestAware;
> public class StudentAction extends ActionSupport implements
> ServletRequestAware { private static final long serialVersionUID =
> -4056538155914479859L; private HttpServletRequest request;
> @Override public void withServletRequest(HttpServletRequest request) {
> this.request = request; }
> public HttpServletRequest getWithServletRequest() { return
>this.request; } public String viewStudent() { return
>"viewStudent"; } public String updateStudent() { return
>"viewStudent"; } public String viewRegistration() { return
>"viewRegistration"; }}
> 7. build.xml<project name="s2ex1" default="war" basedir="."> <!--
> Define global properties --> <property name="src.dir" value="src"/>
> <property name="web.dir" value="WebContent"/> <property name="build.dir"
> value="build"/> <property name="classes.dir"
> value="${build.dir}/classes"/> <property name="war.file"
> value="s2ex1.war"/> <!-- All external libraries --> <property
> name="lib.dir" value="${basedir}/lib"/>
> <!-- Clean --> <target name="clean"> <delete
>dir="${build.dir}"/> <delete file="${war.file}"/> </target>
> <!-- Compile Java sources --> <target name="compile"> <mkdir
>dir="${classes.dir}"/> <javac srcdir="${src.dir}"
>destdir="${classes.dir}" includeantruntime="false" source="21"
> target="21" > <classpath> <fileset
>dir="${lib.dir}"> <include name="*.jar"/>
></fileset> </classpath> </javac> </target>
> <!-- Prepare WAR directory --> <target name="prepare"> <mkdir
>dir="${build.dir}/WebContent"/> <copy todir="${build.dir}/WebContent">
> <fileset dir="${web.dir}"/> </copy> <copy
>file="WebContent/WEB-INF/struts.xml" todir="${build.dir}/WebContent/WEB-INF"/>
> <copy todir="${build.dir}/WebContent/WEB-INF/classes">
><fileset dir="${classes.dir}"/> </copy> <copy
>todir="${build.dir}/WebContent/WEB-INF/lib"> <fileset
>dir="${lib.dir}/"> <include name="struts2-core-7.0.3.jar"/>
> <include name="freemarker-2.3.34.jar"/> <include
>name="ognl-3.3.5.jar"/> <include name="caffeine-3.1.8.jar"/>
><include name="xwork-core-2.3.35.jar"/> </fileset> </copy> </target>
> <!-- Create WAR file --> <target name="war" depends="clean, compile,
>prepare"> <mkdir dir="${build.dir}/WebContent"/> <war
>destfile="${war.file}" webxml="${build.dir}/WebContent/WEB-INF/web.xml">
> <fileset dir="${build.dir}/WebContent"/> </war> <echo
>message="Build file created: ${war.file}"/> </target>
> </project>
> Thank you,Joseph H.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]