留言板

Implementing a servlet in a Liferay MVC portlet in Liferay 7

Zak Thompson,修改在7 年前。

Implementing a servlet in a Liferay MVC portlet in Liferay 7

Junior Member 帖子: 70 加入日期: 16-6-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.
Zak Thompson,修改在7 年前。

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

Junior Member 帖子: 70 加入日期: 16-6-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
Fernando Fernandez,修改在7 年前。

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

Expert 帖子: 396 加入日期: 07-8-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
Zak Thompson,修改在7 年前。

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

Junior Member 帖子: 70 加入日期: 16-6-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
Fernando Fernandez,修改在7 年前。

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

Expert 帖子: 396 加入日期: 07-8-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
Juan Gonzalez,修改在7 年前。

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
Zak Thompson,修改在7 年前。

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

Junior Member 帖子: 70 加入日期: 16-6-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
Mohammad Danish,修改在7 年前。

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

Regular Member 帖子: 187 加入日期: 12-3-5 最近的帖子
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,修改在7 年前。

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