Antti Hätinen created WICKET-5256:
-------------------------------------
Summary: ResourceStreamResource does not setTextEncoding for
StringResourceStream
Key: WICKET-5256
URL: https://issues.apache.org/jira/browse/WICKET-5256
Project: Wicket
Issue Type: Bug
Components: wicket
Affects Versions: 1.5.10
Environment: Ubuntu 12.04, Sun JDK 1.6.0_38 64bit
Reporter: Antti Hätinen
Priority: Minor
During the migration from Wicket 1.4 to 1.5.10 I found out that the
ResourceStreamResource.respond() does not set the ContentType charset if the
resource is of type StringResourceStream. Even though the stream holds the
charset, it is not set, although quite a few other header parameters are (well
this is understandable because not all ResourceStreams are
StringResourceStreams. Also, it is difficult to call the
resource.setTextEncoding, because the current flow in
resourceStreamRequestHandler.respond does not allow easy overriding of any
smaller piece of respond than the whole method. The practical issue was to
download a CSV file by clicking a button. I managed to fix the issue by
copy/paste/Overriding the ResourceStreamRequestHandler.respond, but IMHO this
is not nice:
private void addCsvButton() {
Form<?> form = new Form<Void>("form") {
@Override
protected void onSubmit() {
final String fileName = getFileName("csv");
TableCsvResourceFactory factory = new TableCsvResourceFactory();
final IResourceStream resourceStream =
factory.getResourceStream(tableModel.getObject());
ResourceStreamRequestHandler resourceStreamRequestHandler = new
ResourceStreamRequestHandler(
resourceStream) {
final ContentDisposition contentDisposition =
ContentDisposition.ATTACHMENT;
@Override
public void respond(IRequestCycle requestCycle) {
Attributes attributes = new
Attributes(requestCycle.getRequest(), requestCycle.getResponse());
ResourceStreamResource resource = new
ResourceStreamResource(resourceStream);
resource.setFileName(fileName);
if (contentDisposition != null) {
resource.setContentDisposition(contentDisposition);
} else {
resource.setContentDisposition(Strings.isEmpty(fileName) ?
ContentDisposition.INLINE
: ContentDisposition.ATTACHMENT);
}
final Duration cacheDuration = getCacheDuration();
if (cacheDuration != null) {
resource.setCacheDuration(cacheDuration);
}
+ resource.setTextEncoding("UTF-8");
resource.respond(attributes);
}
};
RequestCycle.get().scheduleRequestHandlerAfterCurrent(resourceStreamRequestHandler);
}
};
form.setVisible(displayCsv);
add(form);
}
There are a couple of problems with the current implementation of
ResourceStreamRequestHandler:
1) I didn't figure out yet any other way how to call the
resource.setTextEncoding("UTF-8");
except by copy/pasting the whole ResourceStreamRequestHandler.respond() code to
the Override. It would be nice, if there would be some cleaner hook to override
some smaller part of this method, such as an empty default implementation of
setTextEncoding() that would be always called but would not do anything for
other types.
2) A second approach would be to create a StringResourceStreamRequestHandler
extends ResourceStreamRequestHandler that would be otherwise the same, but
would use IStringResource instead of IResource, and would also set the
TextEncoding.
3) However, third, I didn't yet find any good way to get the encoding from the
StringResourceStream itself, because the AbstractStringResourceStream has a
protected getCharset(). This problem could be overcome by adding public version
of getCharset() to StringResourceStream, or as I did, create a parallel
subclass CharsetStringResourceStream that is a copy/paste from
StringResourceStream but is non-final and has public getCharset(). After this
you could dynamically set the text encoding in
ResourceStreamRequestHandler.respond for example like this:
if (getResourceStream() instanceof
CharsetStringResourceStream) {
resource.setTextEncoding(((CharsetStringResourceStream)getResourceStream()).getCharsetName());
}
Anyway, I think the usage of StringResourceStream with
ResourceStreamRequestHandler should be improved somehow, at the moment I think
it is a bit awkward to use.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira