-
Notifications
You must be signed in to change notification settings - Fork 67
/
AbstractFileUploadResource.java
159 lines (137 loc) · 5.18 KB
/
AbstractFileUploadResource.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package com.mycompany.fileupload;
import org.apache.wicket.protocol.http.servlet.MultipartServletWebRequest;
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
import org.apache.wicket.request.http.flow.AbortWithHttpErrorCodeException;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.util.lang.Bytes;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.upload.FileItem;
import org.apache.wicket.util.upload.FileUploadException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* The resource that handles the file uploads.
* Reads the file items from the request parameters and uses FileManager
* to store them.
* Additionally cares about the response's content type and body.
*/
public abstract class AbstractFileUploadResource extends AbstractResource
{
private static final Logger LOG = LoggerFactory.getLogger(AbstractFileUploadResource.class);
private final FileManager fileManager;
public AbstractFileUploadResource(FileManager fileManager)
{
this.fileManager = fileManager;
}
/**
* Reads and stores the uploaded files
* @param attributes
* @return
*/
@Override
protected ResourceResponse newResourceResponse(Attributes attributes)
{
final ResourceResponse resourceResponse = new ResourceResponse();
final ServletWebRequest webRequest = (ServletWebRequest) attributes.getRequest();
try
{
MultipartServletWebRequest multiPartRequest = webRequest.newMultipartWebRequest(getMaxSize(), "ignored");
Map<String, List<FileItem>> files = multiPartRequest.getFiles();
List<FileItem> fileItems = files.get(FileUploadBehavior.PARAM_NAME);
saveFiles(fileItems);
prepareResponse(resourceResponse, webRequest, fileItems);
}
catch (Exception fux)
{
LOG.error("An error occurred while uploading a file", fux);
throw new AbortWithHttpErrorCodeException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, fux.getMessage());
}
return resourceResponse;
}
/**
* Sets the response's content type and body
* @param resourceResponse
* @param webRequest
* @param fileItems
* @throws FileUploadException
* @throws IOException
*/
protected void prepareResponse(ResourceResponse resourceResponse, ServletWebRequest webRequest, List<FileItem> fileItems)
throws FileUploadException, IOException {
final String responseContent;
String accept = webRequest.getHeader("Accept");
if (wantsHtml(accept))
{
// Internet Explorer
resourceResponse.setContentType("text/html");
responseContent = generateHtmlResponse(resourceResponse, webRequest, fileItems);
}
else
{
// a real browser
resourceResponse.setContentType("application/json");
responseContent = generateJsonResponse(resourceResponse, webRequest, fileItems);
}
resourceResponse.setWriteCallback(new WriteCallback() {
@Override
public void writeData(Attributes attributes) throws IOException {
attributes.getResponse().write(responseContent);
}
});
}
/**
* Delegates to FileManager to store the uploaded files
* @param fileItems
* @throws IOException
*/
protected void saveFiles(List<FileItem> fileItems) throws IOException {
for (FileItem fileItem : fileItems)
{
fileManager.save(fileItem);
}
}
/**
* Decides what should be the response's content type depending on the 'Accept' request header.
* HTML5 browsers work with "application/json", older ones use IFrame to make the upload and the
* response should be HTML.
* Read http://blueimp.github.com/jQuery-File-Upload/ docs for more info.
* @param acceptHeader
* @return
*/
protected boolean wantsHtml(String acceptHeader)
{
return !Strings.isEmpty(acceptHeader) && acceptHeader.contains("text/html");
}
/**
* Defines what is the maximum size of the uploaded files.
* TODO: integrate this in FileUploadBehavior to set the max size at the client side too
* @return
*/
protected Bytes getMaxSize()
{
return Bytes.megabytes(100);
}
/**
* Should generate the response's body in JSON format
*
* @param resourceResponse
* @param webRequest
* @param files
* @return
*/
protected abstract String generateJsonResponse(ResourceResponse resourceResponse,
ServletWebRequest webRequest, List<FileItem> files);
/**
* Should generate the response's body in HTML format
* @param resourceResponse
* @param webRequest
* @param files
* @return
*/
protected abstract String generateHtmlResponse(ResourceResponse resourceResponse,
ServletWebRequest webRequest, List<FileItem> files);
}