掲示板

Implementing a servlet in a Liferay MVC portlet in Liferay 7

7年前 に Zak Thompson によって更新されました。

Implementing a servlet in a Liferay MVC portlet in Liferay 7

Junior Member 投稿: 70 参加年月日: 16/06/13 最新の投稿
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.
7年前 に Zak Thompson によって更新されました。

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

Junior Member 投稿: 70 参加年月日: 16/06/13 最新の投稿
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
7年前 に Fernando Fernandez によって更新されました。

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

Expert 投稿: 396 参加年月日: 07/08/22 最新の投稿
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
7年前 に Zak Thompson によって更新されました。

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

Junior Member 投稿: 70 参加年月日: 16/06/13 最新の投稿
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
7年前 に Fernando Fernandez によって更新されました。

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

Expert 投稿: 396 参加年月日: 07/08/22 最新の投稿
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
7年前 に Juan Gonzalez によって更新されました。

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

Liferay Legend 投稿: 3089 参加年月日: 08/10/28 最新の投稿
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
7年前 に Zak Thompson によって更新されました。

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

Junior Member 投稿: 70 参加年月日: 16/06/13 最新の投稿
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
7年前 に Mohammad Danish によって更新されました。

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

Regular Member 投稿: 187 参加年月日: 12/03/05 最新の投稿
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
7年前 に Juan Gonzalez によって更新されました。

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

Liferay Legend 投稿: 3089 参加年月日: 08/10/28 最新の投稿
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