How to have a working Textarea and a fileUpload in

2019-08-17 14:35发布

问题:

The Problem

The below test case illustrates my issue. I have a JSF application which uses a HTML form in which I must use enctype="multipart/form-data" since I am using a file upload, see here. However when I use this encoding, newlines entered into my Textarea disappear when submitted to the server.

The text area in result.xhtml always shows all of the text the user entered on index.xhtml on one line, regardless of any newlines the user put in. The output text always evaluates to "False" to reflect that the backing property never receives any text with "\n" or "\r".

Test Case

index.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
            <h:form enctype="multipart/form-data">
                <h:inputTextarea value="#{controller.text}"/>
                <h:inputFile value="#{controller.file}"/>

                <h:commandButton value="Upload and Continue" type = "submit" action="#{controller.respond}"/>
            </h:form>
    </h:body>
</html>

Controller.java

package main;

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.servlet.http.Part;

@Named("controller")
@SessionScoped
public class Controller implements Serializable {
    private static final long serialVersionUID = 1L;
    private String text;
    private boolean containsNewline = false;
    private Part file;

    public String respond() {
        return "result.xhtml";
    }

    public void setText(String value) {
        if (value.contains("\n") || value.contains("\r")) {
            containsNewline = true;
        }
        text = value;
    }
    public String getText() {return text;}
    public String getContainsNewline()
    {
        return String.valueOf(containsNewline);
    }
    public void setFile(Part value) { file = value; }
    public Part getFile() { return file; }
}

result.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
            <h:form>
                <h:inputTextarea value="#{controller.text}"/>
                <h:outputText value="#{controller.containsNewline}"/>
            </h:form>
    </h:body>
</html>

My Theory

I read RFC2388 and from what I understand, multipart/form-data has uses a sequence of characters to delimit Parts in the stream, and reading up on other blogs I saw that it is common to use newline characters as part of the delimiter. Is it possible that my newline characters from my Textarea are getting mixed up into the delimiter ?

The only other thing I can think of, is in RFC2388 4.5, each part is allowed to have its own content-type, which in the case of text data is the charset parameter. How do I set a different charset ? and which one do I use ?

I may even be completely off with the above, these are just my current theories.

Technology I am using

I am using JSF 2.2 and CDI 1.2 running on Websphere Application Server 17.0.0.2. Upgrading to JSF 2.3 is not an option for me, I've already been down that path and ran into unsolvable issues, see these 2 questions on SO: implementing JSF-2.3 and CDI together in WebSphere Application Server and JSF-2.3 not finding my @Named CDI-1.2 managed bean