Issue with Namespace Configuration
Joseph Huynh <[email protected]> Fri, 6 Jun 2025 16:47:45 +0000 (UTC)
| Newsgroups | gmane.comp.jakarta.struts.user |
|---|---|
| Message-ID | <[email protected]> |
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.