Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WW-5371] Documents new Action File Upload Interceptor #223

Merged
merged 3 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 111 additions & 0 deletions source/core-developers/action-file-upload-interceptor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
layout: default
title: Action File Upload Interceptor
parent:
title: Interceptors
url: interceptors
---

# Action File Upload Interceptor

> Available since Struts 6.4.0 as replacement for [File Upload Interceptor](file-upload-interceptor)

See [this page](file-upload) for more examples and advanced configuration.

Interceptor that is based off of `MultiPartRequestWrapper`, which is automatically applied for any request that includes
a file. If an action implements `org.apache.struts2.action.UploadedFilesAware` interface, the interceptor will pass
information and content of uploaded files using the callback method `withUploadedFiles(List<UploadedFile>)`.

See the example code section.

This interceptor will add several field errors, assuming that the action implements `ValidationAware`. These error messages
are based on several i18n values stored in `struts-messages.properties`, a default i18n file processed for all i18n requests.
You can override the text of these messages by providing text for the following keys:

- `struts.messages.error.uploading` - a general error that occurs when the file could not be uploaded
- `struts.messages.error.file.too.large` - occurs when the uploaded file is too large
- `struts.messages.error.content.type.not.allowed` - occurs when the uploaded file does not match the expected content
types specified
- `struts.messages.error.file.extension.not.allowed` - occurs when the uploaded file does not match the expected
file extensions specified

## Parameters

- `maximumSize` (optional) - the maximum size (in bytes) that the interceptor will allow a file reference to be set
on the action. Note, this is <b>not</b> related to the various properties found in struts.properties.
Default to approximately 2MB.
- `allowedTypes` (optional) - a comma separated list of content types (ie: `text/html`) that the interceptor will allow
a file reference to be set on the action. If none is specified allow all types to be uploaded.
- `allowedExtensions` (optional) - a comma separated list of file extensions (ie: `.html`) that the interceptor will allow
a file reference to be set on the action. If none is specified allow all extensions to be uploaded.

## Extending the Interceptor

You can extend this interceptor and override the acceptFile method to provide more control over which files are supported
and which are not.

## Examples

**Example action mapping:**

```xml
<action name="doUpload" class="com.example.UploadAction">
<interceptor-ref name="actionFileUpload"/>
<interceptor-ref name="basicStack"/>
<result name="success">good_result.jsp</result>
</action>

```

Notice the interceptor configuration in the preceding example\.

**Example JSP form tags:**

```xml
<s:form action="doUpload" method="post" enctype="multipart/form-data">
<s:file name="upload" label="File"/>
<s:submit/>
</s:form>

```

You must set the encoding to <code>multipart/form-data</code> in the form where the user selects the file to upload.

**Example Action class:**

```java
public class UploadAction extends ActionSupport implements UploadedFilesAware {
private UploadedFile uploadedFile;
private String contentType;
private String fileName;
private String originalName;

@Override
public void withUploadedFiles(List<UploadedFile> uploadedFiles) {
if (!uploadedFiles.isEmpty() > 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think you can drop the > 0

this.uploadedFile = uploadedFiles.get(0);
this.fileName = uploadedFile.getName();
this.contentType = uploadedFile.getContentType();
this.originalName = uploadedFile.getOriginalName();
}
}

public String execute() {
//do something with the file
return SUCCESS;
}
}
```

**Setting parameters example:**

```xml
<interceptor-ref name="fileUpload">
<param name="allowedTypes">
image/png,image/gif,image/jpeg
</param>
</interceptor-ref>
```

This part is optional and would be done in place of the `<interceptor-ref name="actionFileUpload"/>` line in the action mapping
example above.
4 changes: 3 additions & 1 deletion source/core-developers/file-upload-interceptor.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ layout: default
title: File Upload Interceptor
parent:
title: Interceptors
url: interceptors.html
url: interceptors
---

# File Upload Interceptor

> Since Struts 6.4.0 this interceptor is deprecated, please use Action FileUpload Interceptor instead!

See [this page](file-upload) for more examples and advanced configuration.

Interceptor that is based off of `MultiPartRequestWrapper`, which is automatically applied for any request that includes
Expand Down
51 changes: 43 additions & 8 deletions source/core-developers/file-upload.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
---
layout: core-developers
title: File Upload
parent:
title: Core Developers Guide
url: index
---

# File Upload
Expand All @@ -21,11 +24,13 @@ than the temporary directory and the directories that belong to your web applica
The Struts 2 framework leverages the Commons FileUpload library as a based library to support file upload in the framework.
The library is included in a base Struts 2 distribution.

> NOTE: Since Struts 6.4.0 the `FileUploadInterceptor` is deprecated and you should use `ActionFileUploadInterceptor` instead!

## Basic Usage

The `org.apache.struts2.interceptor.FileUploadInterceptor` class is included as part of the `defaultStack`. As long as
the required libraries are added to your project you will be able to take advantage of the Struts 2 file upload
capability. Configure an Action mapping for your Action class as you typically would.
The `org.apache.struts2.interceptor.FileUploadInterceptor` and `org.apache.struts2.interceptor.ActionFileUploadInterceptor`
classes is included as part of the `defaultStack`. As long as the required libraries are added to your project you will be able
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classes **are** included

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rephrased the sentence a bit

to take advantage of the Struts 2 file upload capability. Configure an Action mapping for your Action class as you typically would.

### Example action mapping:

Expand All @@ -36,9 +41,8 @@ capability. Configure an Action mapping for your Action class as you typically w

```

A form must be create with a form field of type file, `<INPUT type="file" name="upload">`. The form used to upload the
file must have its encoding type set
to `multipart/form-data`, `<form action="doUpload" enctype="multipart/form-data" method="post">`.
A form must be created with a form field of type file, `<INPUT type="file" name="upload">`. The form used to upload the
file must have its encoding type set to `multipart/form-data`, `<form action="doUpload" enctype="multipart/form-data" method="post">`.
The standard procedure for adding these elements is by using the Struts 2 tag libraries as shown in the following
example:

Expand All @@ -51,7 +55,35 @@ example:
</s:form>
```

The fileUpload interceptor will use setter injection to insert the uploaded file and related data into your Action
The actionFileUpload interceptor will use a dedicated interface `org.apache.struts2.action.UploadedFilesAware` to transfer
information and content of uploaded file. Your action should implement the interface to receive the uploaded file:

```java
public class UploadAction extends ActionSupport implements UploadedFilesAware {

private UploadedFile uploadedFile;
private String contentType;
private String fileName;
private String originalName;

@Override
public void withUploadedFiles(List<UploadedFile> uploadedFiles) {
if (!uploadedFiles.isEmpty() > 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

this.uploadedFile = uploadedFiles.get(0);
this.fileName = uploadedFile.getName();
this.contentType = uploadedFile.getContentType();
this.originalName = uploadedFile.getOriginalName();
}
}

public String execute() {
// do something with the file
return SUCCESS;
}
}
```

**Deprecated approach**: the fileUpload interceptor will use setter injection to insert the uploaded file and related data into your Action
class. For a form field named `upload` you would provide the three setter methods shown in the following example:

### Example Action class:
Expand Down Expand Up @@ -119,7 +151,10 @@ see `struts-fileupload.xml` in the sample application download.
</s:form>
```

`MultipleFileUploadUsingArrayAction.java`
The `org.apache.struts2.action.UploadedFilesAware` interface already supports uploading multiple files, you do not need to
follow the below example.

**Deprecated approach**: `MultipleFileUploadUsingArrayAction.java`

```java
public class MultipleFileUploadUsingArrayAction extends ActionSupport {
Expand Down