[
https://issues.apache.org/jira/browse/WW-5546?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17950466#comment-17950466
]
Jesus M commented on WW-5546:
-----------------------------
Sure, Sorry about that. It is I am migrating from 2.5 to 7.x. This is because I
have an app on production and we are taking the time to migrate this app to the
latest version.
I wanted to thoroughly verify what you explained about the new
'UploadedFilesAware' interface. For this reason, I created a minimal test
example to validate the implementation once again - but it still doesn't work.
Previously, I believed there were two possible approaches:
# Using AJAX with direct setters in the VO, or
# Implementing the UploadedFilesAware interface.
While I initially relied on the first approach, I also tested the second option
(following the examples), but neither worked.
Since you've confirmed that the only supported method now is using
UploadedFilesAware, once again I focused entirely on creating a basic project
to ensure proper functionality before migrating it to my main application.
However, I still can't get it to work."
Principal points in my Action:
public class HelloAction extends ActionSupport implements UploadedFilesAware {
private Logger logger = LogManager.getLogger(HelloAction.class);
private List<String> actionErrors; // Mensajes globales de error
private List<String> actionMessages; // Mensajes de éxito
public UploadedFile upload;
private String contentType;
public String fileName;
private String originalName;
@Override
public String execute() {
if (upload == null) {
logger.info("File has an error");
addActionError("We dont have any file :(");
return INPUT;
}
try {
// we gonna process the file...
logger.info("Success uploading file... " + fileName);
return SUCCESS;
} catch (Exception e) {
addActionError("Error al procesar el archivo: " + e.getMessage());
return ERROR;
}
}
@Override
public void withUploadedFiles(List<UploadedFile> uploadedFiles) {
if (!uploadedFiles.isEmpty()) {
this.upload = uploadedFiles.get(0);
this.fileName = upload.getName();
this.contentType = upload.getContentType();
this.originalName = upload.getOriginalName();
}
}
}
My Struts.xml is:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts
Configuration 6.5//EN"
"https://struts.apache.org/dtds/struts-6.5.dtd">
<struts>
<constant name="struts.multipart.parser" value="jakarta" />
<constant name="struts.multipart.maxSize" value="10485760" /> <!-- 10MB -->
<constant name="struts.multipart.saveDir" value="C:\\temp"/> <!-- Ruta
absoluta -->
<package name="default" extends="struts-default">
<action name=""><result>/hello.jsp</result></action>
<action name="hello" class="mx.com.jeser.ejemplo.actions.HelloAction">
<interceptor-ref name="actionFileUpload" />
<interceptor-ref name="basicStack" />
<result name="success">/success.jsp</result>
<result name="input">/input.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package></struts>
My init jsp:
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<title>Struts 7.0.3</title>
</head>
<body>
<s:form action="hello" method="POST" enctype="multipart/form-data">
<s:file name="upload" label="Select a file"/>
<s:submit value="Subir"/>
</s:form>
</body></html>
Result notes:
* Basically in the action I can see upload is null
* The trace:
* 2025-05-09 01:00:25 DEBUG Dispatcher:1036 - Support for multipart request is
enabled: true
2025-05-09 01:00:25 DEBUG Dispatcher:1054 - Validating if this is a proper
Multipart request. Request is POST: true and ContentType matches pattern
(^multipart/form-data(?:\s*;\s*boundary=[0-9a-zA-Z'"()+_,\-./:=?]\{1,70})?(?:\s*;\s*charset=[a-zA-Z\-0-9]\{3,14})?):
true
2025-05-09 01:00:25 DEBUG Dispatcher:1012 - Wrapping multipart request with:
MultiPartRequestWrapper
2025-05-09 01:00:25 DEBUG Dispatcher:926 - saveDir=C:\\temp
2025-05-09 01:00:25 DEBUG JakartaMultiPartRequest:66 - Using file save
directory: C:\temp
2025-05-09 01:00:25 DEBUG JakartaMultiPartRequest:69 - Sets minimal buffer size
to always write file to disk
2025-05-09 01:00:25 DEBUG JakartaMultiPartRequest:72 - Using charset: UTF-8
2025-05-09 01:00:25 DEBUG AbstractMultiPartRequest:196 - Applies max size:
10485760 to file upload request
2025-05-09 01:00:25 DEBUG AbstractMultiPartRequest:200 - Applies max files
number: 256 to file upload request
2025-05-09 01:00:25 DEBUG InstantiatingNullHandler:106 - Entering
nullPropertyValue
[target=[org.apache.struts2.text.DefaultTextProvider@55a6d16f], property=struts]
2025-05-09 01:00:25 DEBUG InstantiatingNullHandler:106 - Entering
nullPropertyValue
[target=[org.apache.struts2.text.DefaultTextProvider@55a6d16f], property=struts]
2025-05-09 01:00:25 DEBUG DefaultActionProxy:88 - Creating an
DefaultActionProxy for namespace [/] and action name [hello]
2025-05-09 01:00:25 DEBUG DefaultActionInvocation:310 - Executing conditional
interceptor: ActionFileUploadInterceptor
2025-05-09 01:00:25 DEBUG ActionFileUploadInterceptor:200 - Found multipart
request: MultiPartRequestWrapper
2025-05-09 01:00:25 DEBUG ActionFileUploadInterceptor:179 - No files have been
uploaded/accepted
* Inspect class ActionFileUploadInterceptor.class acceptedFiles parameter
always is empty, that's reason message "No files have been uploaded/accepted".
I assume there is a problem with the loading.
* Always is present this warning: 2025-05-09 01:00:25 WARN File:79 - Struts
has detected a file upload UI tag (s:file) being used without a form set to
method 'POST'. This is probably an error! But, as you can see method is there.
* I have a question: Does the Struts Parameter notation also apply to this
type of sending?
I would sincerely appreciate some assistance to properly understand this
process, as the implementation isn't working according to the official
documentation!
> NPE in AbstractFileUploadInterceptor
> ------------------------------------
>
> Key: WW-5546
> URL: https://issues.apache.org/jira/browse/WW-5546
> Project: Struts 2
> Issue Type: Bug
> Components: Core, Core Interceptors
> Affects Versions: 6.7.4
> Reporter: Barta Tamás
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 6.8.0, 7.1.0
>
> Time Spent: 1.5h
> Remaining Estimate: 0h
>
> I got the following exception:
>
> {code:java}
> java.lang.NullPointerException: Cannot invoke "java.io.File.length()" because
> "this.file" is null
> at
> deployment.deployment.ear//org.apache.struts2.dispatcher.multipart.StrutsUploadedFile.length(StrutsUploadedFile.java:52)
> at
> deployment.deployment.ear//org.apache.struts2.interceptor.AbstractFileUploadInterceptor.acceptFile(AbstractFileUploadInterceptor.java:133)
> at
> deployment.deployment.ear//org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:232)
> at
> deployment.deployment.ear//com.opensymphony.xwork2.interceptor.AbstractInterceptor.intercept(AbstractInterceptor.java:36)
> at
> deployment.deployment.ear//com.opensymphony.xwork2.DefaultActionInvocation.executeConditional(DefaultActionInvocation.java:303)
> {code}
> I think the bug is in AbstractFileUploadInterceptor:
>
>
> {code:java}
> if (file.getContent() == null) {
> String errMsg = getTextMessage(action,
> STRUTS_MESSAGES_ERROR_UPLOADING_KEY, new String[]{originalFilename});
>
> errorMessages.add(errMsg);
> LOG.warn(errMsg);
> }
> if (maximumSize != null && maximumSize < file.length()) { {code}
> If file.getContent() is null (which means StrutsUploadedFile.file is null),
> then warning is logged but there is no "return false" so execution continues
> and file.length() will throw NPE as file is null in StrutsUploadedFile.
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)