Issue
- Trying to upload image to DXP 7.4 via GraphQL API (createDocumentFolderDocument method).
- This approach seems not be valid after DXP 7.2:
https://help.liferay.com/hc/en-us/articles/360039026272-Multipart-Requests - The approach used in DXP 7.2 now produces the following error:
ERROR [http-nio-8080-exec-7][AbstractGraphQLHttpServlet:86] Error executing GraphQL request!
java.lang.IllegalStateException: getInputStream() has already been called for this request
at org.apache.catalina.connector.Request.getReader(Request.java:1206) ~[catalina.jar:9.0.75]
at org.apache.catalina.connector.RequestFacade.getReader(RequestFacade.java:392) ~[catalina.jar:9.0.75]
at javax.servlet.ServletRequestWrapper.getReader(ServletRequestWrapper.java:213) ~[servlet-api.jar:4.0.FR]
at javax.servlet.ServletRequestWrapper.getReader(ServletRequestWrapper.java:213) ~[servlet-api.jar:4.0.FR]
at javax.servlet.ServletRequestWrapper.getReader(ServletRequestWrapper.java:213) ~[servlet-api.jar:4.0.FR]
at javax.servlet.ServletRequestWrapper.getReader(ServletRequestWrapper.java:213) ~[servlet-api.jar:4.0.FR]
at graphql.kickstart.servlet.GraphQLPostInvocationInputParser.getGraphQLInvocationInput(GraphQLPostInvocationInputParser.java:35) ~[graphql-java-servlet-12.0.0.jar:?]
at graphql.kickstart.servlet.HttpRequestHandlerImpl.handle(HttpRequestHandlerImpl.java:42) ~[graphql-java-servlet-12.0.0.jar:?]
at graphql.kickstart.servlet.AbstractGraphQLHttpServlet.doRequest(AbstractGraphQLHttpServlet.java:84) [graphql-java-servlet-12.0.0.jar:?]
at graphql.kickstart.servlet.AbstractGraphQLHttpServlet.doPost(AbstractGraphQLHttpServlet.java:79) [graphql-java-servlet-12.0.0.jar:?]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:555) [servlet-api.jar:4.0.FR]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) [servlet-api.jar:4.0.FR]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at com.liferay.portal.vulcan.internal.graphql.servlet.GraphQLServletExtender$10.invoke(GraphQLServletExtender.java:654) [bundleFile:?]
at com.sun.proxy.$Proxy470.service(Unknown Source) [?:?]
at org.eclipse.equinox.http.servlet.internal.registration.EndpointRegistration.service(EndpointRegistration.java:153) [bundleFile:?]
Environment
- DXP 7.4
Resolution
- The GraphQL API (createDocumentFolderDocument method) is available in 7.4, and it works as described in the documentation.
- The steps that are required to be made in order to execute the mutation successfully are the following:
- First, locate the Liferay application’s web.xml file, in our case, the
shielded-container-web.xml
file found inside the following path in case the container used is tomcat-9.0.83:bundles/tomcat-9.0.83/webapps/ROOT/WEB-INF/shielded-container-web.xml
- Secondly, modify the servlet configuration of the "Module Framework Servlet" found within the
shielded-container-web.xml
file. This name will be contained between the<servlet-name></servlet-name>
tags. The full "Module Framework Servlet" configuration should look something like:
<servlet>
<servlet-name>Module Framework Servlet</servlet-name>
<servlet-class>com.liferay.portal.module.framework.ModuleFrameworkServletAdapter</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
<multipart-config>
<location>/tmp</location>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841</max-request-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
- Once modified and saved, restart the portal.
- After restarting, execute the mutation query for an existing document folder with an existing document found in your computer. Here's a CURL to achieve that:
curl 'http://localhost:8080/o/graphql' \
-u 'test@liferay.com:test' \
-F operations='{
"query":"mutation($files: [Upload]) {createDocumentFolderDocument(multipartBody: $files, documentFolderId: \"33449\") {id}}",
"variables":{
"files":[
null
]
}
}' \
-F map='{ "0": ["variables.files.0"]}' \
-F 0=@"file.txt"
NOTE: You’d need to modify the authentication, documentFolderId
and file path to your case in order to make the request work.