Forums de discussion

Implementing a servlet in a Liferay MVC portlet in Liferay 7

Zak Thompson, modifié il y a 7 années.

Implementing a servlet in a Liferay MVC portlet in Liferay 7

Junior Member Publications: 70 Date d'inscription: 13/06/16 Publications récentes
I am currently trying to implement asynchronous file uploading using a Servlet in a MVC portlet in Liferay 7 and I'm running into issues configuring the servlet. I've tried looking around the internet for an answer but currently there doesn't seem to be much out there about Liferay 7 and servlets. The need for a servlet comes from the fact that we would like to be able to have users upload multiple files asynchronously without requiring a page refresh.

Here is my current attempt at implementing the servlet:
MVC portlet class:
@Component(
	immediate = true,
	property = {
		"com.liferay.portlet.display-category=category.sample",
		"com.liferay.portlet.instanceable=true",
		"javax.portlet.display-name=audit-view Portlet",
		"javax.portlet.init-param.template-path=/",
		"javax.portlet.init-param.view-template=/view.jsp",
		"javax.portlet.resource-bundle=content.Language",
		"javax.portlet.security-role-ref=power-user,user"
	},
	service = Portlet.class
)
public class AuditViewPortlet extends MVCPortlet {
}


web.xml: (placed in the file path src/main/resources/WEB-INF/web.xml)
<!--?xml version="1.0" encoding="UTF-8"?-->
<web-app id="WebApp_ID" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<display-name>audit-view Portlet</display-name>
	<servlet>
		<servlet-name>DocumentUpload</servlet-name>
		<servlet-class>com.echelon.vm.servlet.DocumentUpload</servlet-class>
	</servlet>
	<servlet-mapping>
	    <servlet-name>DocumentUpload</servlet-name>
	    <url-pattern>/documentUpload</url-pattern>
	</servlet-mapping>
	
</web-app>


DocumentUpload Servlet:

package com.echelon.vm.servlet;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DocumentUpload extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1488294707145038780L;
	
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response){
		System.out.println("Hello");
	}

}



I am currently trying to access the servlet by hitting the URL "localhost:8080/o/auditview/documentUpload", and I am getting the following error on my console: "[http-nio-8080-exec-2][code_jsp:181] {code="404", msg="ProxyServlet: /o/auditview/documentUpload", uri=/o/auditview/documentUpload}" My expected response is "Hello" being logged to the console.

However, if I go to the URL "localhost:8080/o/auditview" I get a HTTP 200 with no content displayed. I got the "/o/auditview" as the url for the portlet by adding the following code to the init.jsp of the portlet:
<aui:script>
    console.log("${pageContext.request.contextPath}");
</aui:script>


If anyone could explain where I'm going wrong I'd greatly appreciate it.
Zak Thompson, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Junior Member Publications: 70 Date d'inscription: 13/06/16 Publications récentes
I've been messing around with this and I think the issue is that the portlet is not picking up the web.xml file and thus not registering the servlet. Should servlets still be registered in a web.xml, and if so, where is the proper place to put the web.xil file in the module?
thumbnail
Fernando Fernandez, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Expert Publications: 396 Date d'inscription: 22/08/07 Publications récentes
Hi Zak,

Are you sure you need a servlet?

I think that AJAX + YourPortlet.serveResource() can do most of the transfers between the browser and the portlet. No?

HTH

Fernando
Zak Thompson, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Junior Member Publications: 70 Date d'inscription: 13/06/16 Publications récentes
Is it possible to send multiple serveResource() calls from the same page without requiring a refresh?

The workflow I'm trying to implement is that there is a step displayed that has multiple substeps. Each substep has uploaded images and comments. The container for all the steps, the steps, the substeps and comments are all tables in service builder. When the step container is created, it also creates a folder path unique to that step container (via DLAppLocalServiceUtil) and saves that folderId in the servicebuilder table. When an image is uploaded, the folderId will be sent with it, and the image will be uploaded to that folder.

The user should be able to upload any images/comments asynchronously without requiring a page refresh (Comments are submitted asynchronously via the service builder JSON api, as far as I know there is no way to send images via the servicebuilder api hence why I went for a servlet). Users on average will be uploading 15-20 images per step (around 3-4 per substep), as well as adding comments, so we want to keep this all asynchronous as requiring 15-20 page refreshes would be a horrible user experience. My understanding of portlets is that any actioncommands require a redirect, which is why I originally targeted the servlet as the way to implement this.
thumbnail
Fernando Fernandez, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Expert Publications: 396 Date d'inscription: 22/08/07 Publications récentes
Zak Thompson:
Is it possible to send multiple serveResource() calls from the same page without requiring a refresh?


Sure. You just use AJAX to call the ResourceURL as many times you want.

HTH

Fernando
thumbnail
Juan Gonzalez, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Liferay Legend Publications: 3089 Date d'inscription: 28/10/08 Publications récentes
Hi Zak.

Zak Thompson:
I've been messing around with this and I think the issue is that the portlet is not picking up the web.xml file and thus not registering the servlet. Should servlets still be registered in a web.xml, and if so, where is the proper place to put the web.xil file in the module?


Exactly, in order to convert your OSGI jar into a WAB, you should put Web-ContextPath in bnd so it gets into MANIFEST. Please check this example:

https://github.com/liferay/liferay-portal/blob/master/modules/apps/mail-reader/mail-reader-web/bnd.bnd#L4
Zak Thompson, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Junior Member Publications: 70 Date d'inscription: 13/06/16 Publications récentes
I've gotten the servlet to work, but I'm encountering something weird with my JSPs. In order to get the web.xml to be read properly, the path had to be: src/main/resources/WEB-INF/web.xml.

However, the new issue I'm encountering is that my JSP's are no longer displaying any output for the portlet.

Init JSP:
&lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt;

&lt;%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %&gt;

&lt;%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %&gt;
&lt;%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %&gt;
&lt;%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %&gt;
&lt;%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %&gt;

<liferay-theme:defineobjects />

<portlet:defineobjects />

<aui:script>
    console.log("${pageContext.request.contextPath}");
</aui:script>


View JSP:
&lt;%@ include file="/init.jsp" %&gt;

<p>
	<b><liferay-ui:message key="audit_view_AuditView.caption" /></b>
</p>

<aui:script>
    console.log("Hello");
</aui:script>


bnd.bnd
Bundle-SymbolicName: audit.view
Bundle-Version: 1.0.0
Web-ContextPath: /auditview


Based on this I should be seeing two messages logged to the javascript console as well as a message be displayed in the portlet body, but there is no output. However, my URL endpoints work for the servlet.

In the view.jsp and init.jsp, all of the liferay and aui tags also have yellow lines underneath them, while they do not in a freshly created blank MVC portlet. However, hovering the mouse over the lines yield no description as to what is generating the line.


EDIT: I've figured out what is causing the issue but I'm unsure of how to resolve it. If you create a new Liferay MVC portlet, it will display the Hello from XXX JSP message. However, once you add a WEB-INF folder to the resources folder, it prevents the JSP messages from being displayed. I'm guessing that by adding the WEB-INF folder it starts looking for the jsps in a different place, so no output is displayed in the deployed portlet.
thumbnail
Mohammad Danish, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Regular Member Publications: 187 Date d'inscription: 05/03/12 Publications récentes
Hi Zak,

It seems that the best suited portlet type for you is Spring MVC portlet. Liferay 7 does support that and can be build using the liferay IDE. It can have multiple ServeResource Methods. So you can have multiple methods in the Controller corresponding to each of your step.

HTH
Thanks
thumbnail
Juan Gonzalez, modifié il y a 7 années.

RE: Implementing a servlet in a Liferay MVC portlet in Liferay 7

Liferay Legend Publications: 3089 Date d'inscription: 28/10/08 Publications récentes
Additionally, I think you need Bundle-SymbolicName too in order to make a WAB that Liferay can "understand".

Please read here for more info:

https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/packaging-a-jsf-application