Skip to content

Servlet 3 multipart parameter binding does not work on Weblogic12c (12.1.2.0) [SPR-11074] #15700

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

Closed
spring-projects-issues opened this issue Nov 6, 2013 · 20 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Nov 6, 2013

Kazuki Shimizu opened SPR-11074 and commented

[Execution Conditions]

  • Weblogic Server 12c(12.1.2.0)
  • Using Upload functionality of Servlet 3 specification
  • Form data(upload file & other item) is bound to form object(form backing bean).

[Execution Result]

Upload file(MultipartFile) is bound to Form object, but other item is not bound to Form object.

h4.[Example code(overview)]

[jsp]
 <form:form action="${pageContext.request.contextPath}/upload/flow" 
                     method="post" 
                     enctype="multipart/form-data"
                     modelAttribute="fileUploadForm">

    <form:input type="file" path="file" />
    <form:input path="description" />
    <form:button name="confirmAndUpload">Confirm</form:button>

</form:form>

[web.xml]
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:META-INF/spring/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <multipart-config>
    </multipart-config>
</servlet>
[weblogic.xml]
<container-descriptor>
    <prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
[spring-mvc.xml]
<bean id="multipartResolver" 
           class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />
[Form object]
public class FileUploadForm implements Serializable {
    private MultipartFile file;
    private String description;
    // omitted
}
[Controller]
@RequestMapping(method = RequestMethod.POST, params = "confirmAndUpload")
public String confirmAndUpload(FileUploadForm form) {
    // omitted
}

h4.[Detail example code]
Please see following page.

[jsp]

[controller]

h4.Other information

  • Tomcat7 & Resin4.0 is succeed by the same source code.

Affects: 3.2.4

Issue Links:

Backported to: 3.2.9

0 votes, 5 watchers

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

I tried to the following code.

[Controller]
@RequestMapping(method = RequestMethod.POST, params = "confirmAndUpload")
public String confirmAndUpload(FileUploadForm form,@RequestParam("description") String description) {
    System.out.println("description :" + description);
    // omitted
}

Input value(description) was outputted to console.
But not bound to form object.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

It works on Tomcat and Resin but not WebLogic is that correct? You can try stepping through WebRequestDataBinder.bind with a debugger.

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

Thanks for giving the information for debug.
I will try to debug & feedback later.

It works on Tomcat and Resin but not WebLogic is that correct?
yes.
Tomcat7 and Resin4.0 is worked. But Webloing12c(12.1.2.0) is not worked.

note:
File is uploaded on the weblogic. But other form data is not bind to form object.

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

I was debugging...

h6.[overview of result]

HttpServletRequest#getParameterNames is returnd empty enumeration on weblogic12c.
therefore, not bind to form object.

h6.[detail of result]
Caller position of HttpServletRequest#getParameterNamesis is about 646 lines of ServletRequestParameterPropertyValues#getParametersStartingWith(ServletRequest, String).

Caller hierarchy is ServletRequestBinder#bind -> ServletRequestParameterPropertyValues(ServletRequest) -> ServletRequestParameterPropertyValues#getParametersStartingWith(ServletRequest, String).

h4.[way to solved]
I tried to following:
Result is worked on weblogic. And tomcat & resin worked by same code.

h6.[extends class of StandardServletMultipartResolver]

public class StandardServletMultipartResolverSupportedForWeblogic extends StandardServletMultipartResolver {

    @Override
    public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
        return new StandardMultipartHttpServletRequest(request) {
            public Enumeration<String> getParameterNames() {
                Enumeration<String> parameterNames = request.getParameterNames();
                if (parameterNames.hasMoreElements()) {
                    return parameterNames;
                }
                List<String> parameterNameList = new ArrayList<String>();
                try {
                    for (Part part : request.getParts()) {
                        if (request.getParameter(part.getName()) != null) {
                            parameterNameList.add(part.getName());
                        }
                    }
                } catch (IOException e) {
                    throw new IllegalArgumentException(e);
                } catch (ServletException e) {
                    throw new IllegalArgumentException(e);
                }
                return Collections.enumeration(parameterNameList);
            }

        };
    }

}

h6.[spring-mvc.xml]

<bean id="multipartResolver" class="org.terasoluna.gfw.examples.upload.prototype.StandardServletMultipartResolverSupportedForWeblogic" />

This source is a prototype ...
I hope that please changed with in Spring Framwork's policy.

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

But multibyte character was garbage characters when specified enctype="multipart/form-data" on weblogic.

ex)
input : ああ(language is japanese)
output : ��

CharacterEncodingFilter is already setting.
Do you know something reason?

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

added Reference URL of OTN Thread. This thread owner is me.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Thanks for debugging. It sounds like a bug in WebLogic. There are parameters but getParameterNames doesn't return their names.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

I am resolving this for now as it appears to be an issue in WebLogic. Keep in mind you can re-open the issue if necessary. And of course feel free to add further comments, that will likely help others.

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

I think it may not be said to be a issue in weblogic ...
Because, servlet 3 specification does not mention about getParameterNames() .
Instead, mentions about getParameter(String) & getParameterValues(String) in servlet 3 specification.
Weblogic is satisfies this specifications.

Servlet 3 specification see following:

http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf?AuthParam=1384191760_2b0fcb1f5298dd0cb12f9e8ce324ef1b
[3.2 File upload(P.22-23)]

What would you say?

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

Hi , Rossen!
Long time no see...

I think implementation of WebLogic are satisfies the API specification of Servlet 3.
Reason see above comment.
If possible, please modify the bind logic of ServletRequestDataBinder#bind method.

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

Please see above comment.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

If we can't rely on getParameterNames exposing the multipart files, then our StandardMultipartHttpServletRequest will have to override getParameterNames and add the multipart names accordingly (if not already present). We're doing that in DefaultMultipartHttpServletRequest (used with Commons FileUpload) as well, so we should be able to add similar logic to StandardMultipartHttpServletRequest.

I'll try that approach tonight, making the fix available in the next 3.2.9 and 4.0.5 snapshots. Would be great if you could give it a try tomorrow...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

Thanks!
I want try snapshot version.

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

Thank you resolve this issue. I will apply my application later.

and ...
I found way to resolve garbage characters on WebLogic.
Append the charset parameter into enctype attribute of form element.
it was easy...

e.g.)

<form:form action="${pageContext.request.contextPath}/upload/single" 
                  method="post"
                  enctype="multipart/form-data;charset=UTF-8"
                  modelAttribute="fileUploadForm">

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

sorry... above comment is wrong.
file upload did not work...

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 18, 2014

Juergen Hoeller commented

The snapshots are available in the meantime. Looking forward to your test results... You can find the Maven coordinates for our 3.2.9 & 4.0.5 snapshot releases at: http://projects.spring.io/spring-framework/

It would be great if you could give the same snapshot a try on Tomcat 7 and Resin 4 too (if you have them around, since you mentioned them above).

As a side note: In the same commit, I've also addressed #16352 and introduced a "resolveLazily" bean property (default is "false") on StandardServletMultipartResolver. Setting that flag to "true" lazily resolves the multipart content on first access of parameters or files... If you're up for it, you could give that mode a try as well. The advantage there is that multipart parsing exceptions occur as late as possible, typically right there when you access parameters or files, which allows for those exceptions to be treated in handler methods.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

I confirmed that was resolved the this issue in 3.2.9.BUILD-SNAPSHOT.
On WebLogic 12c and Tomcat 7 and Resin 4, it was no problem.
Also, i tried sets "true" to StandardServletMultipartResolver#resolveLazily on above three AP Server, it was no problem.

Thank you for resolve.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Thanks for the immediate feedback!

FYI, we'll release both 4.0.5 and 3.2.9 tomorrow night, for public availability on Tuesday.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

On a last minute note, I've added dedicated getParameterMap() merging as well, since that method isn't mentioned in the Servlet spec for file upload purposes either. So StandardMultipartHttpServletRequest overrides both getParameterNames() and getParameterMap() in the same style now, completing the entries if necessary. This is also in line with
CommonsMultipartResolver's DefaultMultipartHttpServletRequest now which overrides both methods as well (next to getParameter and getParameterValues itself, as needed there).

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

Additional information:
Garbage characters of form items on WebLogic has been resolved at 12c R2(12.2.1).

Thanks.

@spring-projects-issues spring-projects-issues added type: bug A general bug status: backported An issue that has been backported to maintenance branches in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 4.0.5 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants