Sure, my web.xml looks like this: <?xml version="1.0" encoding="UTF-8"?> <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_6_0.xsd" version="6.0"> <display-name>Struts Blank</display-name> <!-- 1. Context Parameter para Log4j2 --> <context-param> <param-name>log4jConfiguration</param-name> <param-value>/WEB-INF/classes/log4j2.xml</param-value> </context-param> <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> </web-app> I forgot also show my struts.xml: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN" "https://struts.apache.org/dtds/struts-6.0.dtd"> <struts> <constant name="struts.ui.theme" value="simple"/> <!-- En struts.xml --> <constant name="struts.ui.templateDir" value="template"/> <constant name="struts.ui.templateSuffix" value="ftl"/> <constant name="struts.devMode" value="true"/> <constant name="struts.enable.DynamicMethodInvocation" value="false"/> <constant name="struts.logging.fileUploadInterceptor" value="TRACE"/> <constant name="struts.logging.level" value="TRACE"/> <constant name="struts.multipart.parser" value="mx.com.struts.action.DebugMultiPartRequest"/> <!-- Using my custom DebugMultiPartRequest --> <package name="default" extends="struts-default"> <action name=""> <result>/index.jsp</result> </action> <action name="hello" class="mx.com.struts.action.HelloAction"> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> </action> </package> </struts> On the log I can see that I don't have file on my action: 2025-06-03 12:48:20 DEBUG ActionFileUploadInterceptor:200 - Found multipart request: MultiPartRequestWrapper 2025-06-03 12:48:20 DEBUG ActionFileUploadInterceptor:179 - No files have been uploaded/accepted Now I can see is blocked!. I was reading that this message is normal on the log: 2025-06-03 12:48:21 DEBUG DefaultAcceptedPatternsChecker:115 - Sets accepted patterns to [[\w+((\.\w+)|(\[\d+])|(\(\d+\))|(\['(\w-?|[\u4e00-\u9fa5]-?)+'])|(\('(\w-?|[\u4e00-\u9fa5]-?)+'\)))*]], note this impacts the safety of your application! 2025-06-03 12:48:21 DEBUG StrutsUrlEncoder:38 - Using default encoding: UTF-8 2025-06-03 12:48:21 DEBUG SecurityMemberAccess:142 - Checking access for [target: mx.com.struts.action.HelloAction@4489b4fa, member: private org.apache.struts2.dispatcher.multipart.UploadedFile mx.com.struts.action.HelloAction.miLogo, property: miLogo] 2025-06-03 12:48:21 WARN SecurityMemberAccess:174 - Access to non-public [private org.apache.struts2.dispatcher.multipart.UploadedFile mx.com.struts.action.HelloAction.miLogo] is blocked! 2025-06-03 12:48:21 DEBUG InstantiatingNullHandler:106 - Entering nullPropertyValue [target=[mx.com.struts.action.HelloAction@4489b4fa, org.apache.struts2.text.DefaultTextProvider@287a1ff7], property=miLogo] As comment I changed file name as miLogo because I was trying use a different name like upload. Thanks for the support. JMC El lun, 2 jun 2025 a las 23:44, Zoran Avtarovski (<zo...@sparecreative.com>) escribió: > Hi Jesus, > > What does your web.xml look like with regards to the struts filters? We > had a similar issue which was resolved by moving to the combined > StrutsPrepareAndExecuteFilter. Sitemesh also played a part in our issue, > but I think by what you are seeing it's worth trying. > > Z. > > On 1/6/2025 6:29 am, Jesus Moreno wrote: > > Hi Lukasz, thanks for your appreciated comments. > > > > I would like to explain in more detail what we have done to try to find > the > > problem and solve it. Here the context: > > > > This is my environment: > > > > - Struts Version: 7.0.3 > > - Java Version: 17 > > - Servlet Container: Apache Tomcat 10.1.36 > > - Key Dependencies (pom): > > - struts2-core:7.0.3 > > - struts2-convention-plugin:7.0.3 > > - struts2-json-plugin:7.0.3 > > - jakarta.servlet-api:5.0.0 > > - log4j-core:2.17.2 > > - Enforced exclusions: javax.servlet:*, javax.activation:* > > > > We've created a basic Maven project (standard archetype) with a simple > file > > upload form containing: > > - 4 regular text fields (working correctly with > > @StrutsParameter(depth=0)) > > - 1 file upload field (<input type="file" name="upload">) > > > > This is my basic jsp: > > > > <%@ page contentType="text/html; charset=UTF-8" %> > > <%@ taglib prefix="s" uri="/struts-tags" %> > > <!DOCTYPE html> > > <html> > > <head> > > <title>File upload result</title> > > </head> > > <body> > > <h1>Hola Mundo desde la tierra...</h1> > > <form action="hello" method="post" enctype="multipart/form-data"> > > <input type="text" name="name"/> > > <input type="text" name="lastname"/> > > <input type="text" name="gender"/> > > <input type="text" name="age"/> > > <input type="file" name="*upload*"/> > > <input type="submit" value="Subir" /> > > </form> > > </body> > > </html> > > > > Expected Behavior: > > > > - When implementing UploadedFilesAware, the framework should: > > - Detect multipart requests > > - Process uploaded files through withUploadedFiles(List<UploadedFile>) > > - Make files available to the action > > > > Where my action looks like: > > > > import org.apache.logging.log4j.LogManager; > > import org.apache.logging.log4j.Logger; > > import org.apache.struts2.ActionSupport; > > import org.apache.struts2.action.UploadedFilesAware; > > import org.apache.struts2.dispatcher.multipart.UploadedFile; > > import org.apache.struts2.interceptor.parameter.StrutsParameter; > > > > public class HelloAction extends ActionSupport implements > > UploadedFilesAware { > > private static final long serialVersionUID = 1L; > > private Logger logger = LogManager.getLogger(HelloAction.class); > > > > private UploadedFile upload; > > private String uploadFileName; > > private String uploadContentType; > > > > @StrutsParameter(depth = 0) > > public String name; > > > > @StrutsParameter(depth = 0) > > public String lastname; > > > > @StrutsParameter(depth = 0) > > public String gender; > > > > @StrutsParameter(depth = 0) > > public String age; > > > > @Override > > public String execute() { > > logger.info("Executing execute method..." + this.uploadFileName); > > return SUCCESS; > > } > > public UploadedFile getUpload() { > > return upload; > > } > > public void setUpload(UploadedFile upload) { > > this.upload = upload; > > } > > public String getUploadFileName() { > > return uploadFileName; > > } > > public void setUploadFileName(String uploadFileName) { > > this.uploadFileName = uploadFileName; > > } > > public String getUploadContentType() { > > return uploadContentType; > > } > > public void setUploadContentType(String uploadContentType) { > > this.uploadContentType = uploadContentType; > > } > > public Logger getLogger() { > > return logger; > > } > > public void setLogger(Logger logger) { > > this.logger = logger; > > } > > public String getName() { > > return name; > > } > > public void setName(String name) { > > this.name = name; > > } > > public String getLastname() { > > return lastname; > > } > > public void setLastname(String lastname) { > > this.lastname = lastname; > > } > > public String getGender() { > > return gender; > > } > > public void setGender(String gender) { > > this.gender = gender; > > } > > public String getAge() { > > return age; > > } > > public void setAge(String age) { > > this.age = age; > > } > > > > @Override > > public void withUploadedFiles(List<UploadedFile> uploadedFiles) { > > if (uploadedFiles != null && !uploadedFiles.isEmpty()) { > > UploadedFile firstFile = uploadedFiles.get(0); // Take the > file > > this.upload = firstFile; > > this.uploadFileName = firstFile.getName(); // String > > this.uploadContentType = firstFile.getContentType(); // > String > > logger.info("File name: " + uploadFileName); > > } > > } > > > > Actual Behavior: > > Despite proper multipart request detection: > > > > The interceptor finds the request wrapper: > > > > 2025-05-31 DEBUG ActionFileUploadInterceptor:200 - Found multipart > request: > > MultiPartRequestWrapper > > > > *Our custom DebugMultiPartRequest confirms file presence:* > > > > 2025-05-31 12:00:13 INFO DebugMultiPartRequest:26 - Todos los parámetros > > del request: > > 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - nombre: Jesus > > 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - apellido: Moreno > > 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - sexo: M > > 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - edad: 50 > > > > > > > > *2025-05-31 12:00:13 INFO DebugMultiPartRequest:39 - Part 'upload' > > encontrada:2025-05-31 12:00:13 INFO DebugMultiPartRequest:40 - - > Nombre: > > Adaware.jpg2025-05-31 12:00:13 INFO DebugMultiPartRequest:41 - - > Tamaño: > > 25546*2025-05-31 12:00:13 DEBUG InstantiatingNullHandler:106 - Entering > > nullPropertyValue > > [target=[org.apache.struts2.text.DefaultTextProvider@2a580722], > > property=struts] > > 2025-05-31 12:00:13 DEBUG ConfigurationManager:180 - Checking > > ConfigurationProviders for reload. > > 2025-05-31 12:00:13 DEBUG InstantiatingNullHandler:106 - Entering > > nullPropertyValue > > [target=[org.apache.struts2.text.DefaultTextProvider@2a580722], > > property=struts] > > 2025-05-31 12:00:13 DEBUG DefaultActionProxy:88 - Creating an > > DefaultActionProxy for namespace [/] and action name [hello] > > 2025-05-31 12:00:14 DEBUG DefaultActionInvocation:310 - Executing > > conditional interceptor: ActionFileUploadInterceptor > > 2025-05-31 12:00:14 DEBUG ActionFileUploadInterceptor:200 - Found > multipart > > request: MultiPartRequestWrapper > > > > But the interceptor reports: > > > > *2025-05-31 12:00:14 DEBUG ActionFileUploadInterceptor:179 - No files > have > > been uploaded/accepted* > > > > Investigation Steps Taken: > > > > 1. Verified all prerequisites: > > - Form uses enctype="multipart/form-data" > > - Using DTD 6.0 as suggested > > - Regularly cleaning Tomcat's work directory > > - Confirmed Jakarta EE 9+ compatibility > > > > 2. Created extensive debug instrumentation: > > - Custom DebugMultiPartRequest shows files reach the server > > - Interceptor-level logging confirms the disconnect > > > > Technical Findings: > > > > 1. The MultiPartRequestWrapper appears to lose file references between: > > - Initial parsing (where files are detectable via raw Part API) > > - Interceptor processing phase > > > > 2. Key suspicious behavior: > > - getFileParameterNames() returns empty enumeration > > - Despite request.getPart("upload") working correctly > > > > Finally As you suggested, we've: > > > > - Consistently cleaned deployment directories > > - Verified DTD compatibility > > - Followed migration guides carefully > > - Yet the team remains persistent in investigating this apparent > > framework bug rather than working around it. > > > > # Summary > > Files are received by the server (confirmed via custom > > DebugMultiPartRequest) but ActionFileUploadInterceptor fails to process > > them via UploadedFilesAware interface in Struts 7.0.3 (Jakarta EE > 9/Tomcat > > 10 environment). > > > > This is my custom DebugMultiPartRequest: > > > > public class DebugMultiPartRequest extends JakartaMultiPartRequest { > > private static final Logger logger = > > LogManager.getLogger(DebugMultiPartRequest.class); > > @Override > > public void parse(HttpServletRequest request, String saveDir) throws > > IOException { > > super.parse(request, saveDir); // Procesa el request normalmente > > logger.info("=== DebugMultiPartRequest (Struts 7) ==="); > > // 1. Listar TODOS los parámetros del request (no solo archivos) > > logger.info("Todos los parámetros del request:"); > > Enumeration<String> paramNames = request.getParameterNames(); > > while (paramNames.hasMoreElements()) { > > String name = paramNames.nextElement(); > > logger.info(" - " + name + ": " + > request.getParameter(name)); > > } > > // 2. Listar partes multipart (alternativa para Jakarta EE 9+) > > if (request instanceof jakarta.servlet.http.HttpServletRequest > > jakartaRequest) { > > jakarta.servlet.http.Part part; > > try { > > part = jakartaRequest.getPart("upload"); > > if (part != null) { > > > > > > > > * logger.info<http://logger.info>("Part 'upload' encontrada:"); > > logger.info<http://logger.info>(" - Nombre: " + > > part.getSubmittedFileName()); logger.info<http://logger.info>(" - > Tamaño: > > " + part.getSize());* } else { > > logger.info("❌ Parte 'upload' NO encontrada en el > request."); > > } > > } catch (IOException e) { > > // TODO Auto-generated catch block > > e.printStackTrace(); > > } catch (ServletException e) { > > // TODO Auto-generated catch block > > e.printStackTrace(); > > } // Nombre de tu campo > > > > } > > } > > } > > > > After this investigation, we appreciated your feedback if there's any > > version where this issue we've identified has been resolved, or how we > can > > make file uploads work properly. > > > > Regards > > JMC > > > > > > El mié, 14 may 2025 a las 0:09, Lukasz Lenart (<lukaszlen...@apache.org > >) > > escribió: > > > >> sob., 10 maj 2025 o 07:09 Jesus Moreno<jesus...@gmail.com> napisał(a): > >>> 2025-05-09 01:00:25 WARNFile:79 - Struts has detected a file upload UI > >> tag > >>> (s:file) being used without a form set to method 'POST' > >>> (Despite <s:form method="POST" enctype="multipart/form-data"> being > >>> correctly declared) > >> This can be related to cached JSP files, please remove them from the > >> container "temp" folder or "work" folder. > >> > >> > https://cwiki.apache.org/confluence/display/WW/Struts+6.x.x+to+7.x.x+migration#Struts6.x.xto7.x.xmigration-Temp/WorkdirectoryofApplicationServer/ServletContainer > >> > >>> struts.xml: > >>> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts > >>> Configuration 6.5//EN" > >>> "https://struts.apache.org/dtds/struts-6.5.dtd"> > >> There is no such version as 6.5, use 6.0 instead > >> https://struts.apache.org/dtds/ > >> > >> > >> Cheers > >> Łukasz > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail:user-unsubscr...@struts.apache.org > >> For additional commands, e-mail:user-h...@struts.apache.org > >> > >> -- Ing. Jesús Moreno Canseco Tel.: (55)6377-0600 Cel.: 55-1409-5156 jesus...@gmail.com <jmor...@ismarts.com.mx>