Not able to call processAction of Portlet - liferay

My game.jsp code -
<%#page import="java.io.Console"%>
<%#page import="com.liferay.portal.kernel.util.WebKeys"%>
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<portlet:defineObjects />
<script>
function updateGames() {
document.getElementById("gameForm").submit();
}
</script>
<portlet:actionURL name="sampleActionUrl" var="sampleActionUrl">
</portlet:actionURL>
<form id="gameForm" action="${sampleActionUrl}">
<div onclick="updateGames()">CLICK HERE</div>
</form>
My Portlet Code -
package com.home;
import java.io.IOException;
public class Game extends GenericPortlet {
#Override
#RenderMode(name = "VIEW")
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
response.setContentType(request.getResponseContentType());
PortletContext context = getPortletContext();
PortletRequestDispatcher rd = context
.getRequestDispatcher("/WEB-INF/jsp/game.jsp");
System.out.println("Game.doView() >> rendering");
rd.include(request, response);
}
#Override
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
System.out.println("Game.processAction() >> processAction");
}
}
When the Form is submitted on click of the div.
doView gets called for rendering the portlet, but not the processAction.
Is there anything I am missing?

Please use below code and give a try
<portlet:actionURL name="sampleActionUrl" var="sampleActionUrl">
</portlet:actionURL>
<form id="gameForm" action="<%=sampleActionUrl.toString()%>" method="post">
<input type="hidden" id="env" name="env"/>
<div onclick="updateGames()">CLICK HERE</div>
</form>
<script>
function updateGames() {
document.getElementById("env").value = 'DEV';
document.getElementById("gameForm").submit();
}
</script>
If you are not using JSTL then you can use <%=sampleActionUrl.toString()%> instead of ${sampleActionUrl}
update
remove below piece of code
#RenderMode(name = "EDIT")

First check that you have set the following in WEB-INF\portlet.xml
<portlet>
...
<portlet-class>com.home.Game</portlet-class>
...
</portlet>

Related

I am working on a MVC Portlet and the document i am saving is not going to db

Here is my Action Class, where I have to save any document to database but its not working and getting error in console that NoSuchMethodException (javax.portlet.ActionRequest, javax.portlet.ActionResponse)
package com.test.docupload;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.PortletException;
import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.captcha.CaptchaMaxChallengesException;
import com.liferay.portal.kernel.captcha.CaptchaTextException;
import com.liferay.portal.kernel.captcha.CaptchaUtil;
import com.liferay.portal.kernel.dao.jdbc.OutputBlob;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.upload.UploadRequest;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.test.docup.model.Doc;
import com.test.docup.service.DocLocalServiceUtil;
/**
* Portlet implementation class DocumentUploadAction
*/
public class DocumentUploadAction extends MVCPortlet {
public void addDoc(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {
UploadRequest uploadRequest = PortalUtil.getUploadPortletRequest(resourceRequest);
File docImage = uploadRequest.getFile("doc");
String title = ParamUtil.getString(uploadRequest, "firstName");
InputStream fis = new FileInputStream(docImage);
OutputBlob dataOutputBlob = new OutputBlob(fis, docImage.length());
try {
Doc doc = DocLocalServiceUtil.createDoc(CounterLocalServiceUtil.increment());
doc.setDocName(title);
doc.setOwner(10199);
doc.setData(dataOutputBlob);
doc = DocLocalServiceUtil.addDoc(doc);
if (doc != null) {
SessionMessages.add(resourceRequest.getPortletSession(), "document-added-success");
System.out.println("document-added-success");
} else {
SessionErrors.add(resourceRequest.getPortletSession(), "document-added-failed");
System.out.println("document-added-failed::");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here is my jsp
<%#page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%# include file="init.jsp" %>
<c:if test='<%=SessionMessages.contains(renderRequest.getPortletSession(),"document-added-success")%>'>
<liferay-ui:success key="document-added-success" message="Document has been added successfully." />
</c:if>
<c:if test='<%=SessionMessages.contains(renderRequest.getPortletSession(),"document-added-failed")%>'>
<liferay-ui:error key="document-added-failed" message="Document Uploaded failed." />
</c:if>
<portlet:actionURL var="addDocActionURL" name="addDoc"></portlet:actionURL>
<aui:form action="<%= addDocActionURL %>" method="post" name="fm" enctype="multipart/form-data">
<aui:input name="title" value="" label="Doc Title"/>
<aui:input name="Doc" value="" type="file" label="Select Doc"/>
<aui:button-row>
<aui:button type="submit" />
</aui:button-row>
</aui:form>
I have changed the ActionRequest to ResourceRequest but still its not working.
There are certain mistakes in your code:
You forgot to include tag reference for aui in your JSP.
Attribute name for file type input was name="Doc", and you were getting parameter value in your action as
File docImage = uploadRequest.getFile("doc");
It should be consistent, either "Doc" / "doc" in both view and action.
You created URL using <portlet:actionURL> tag but were linking it to action type:
public void addDoc(ResourceRequest resourceRequest, ResourceResponse
resourceResponse)
throws IOException, PortletException {
which is valid for the URL created using <portlet:resourceURL> tag. For actionURL your action method should be:
public void addDoc(ActionRequest actionRequest, ActionResponse
actionResponse)
throws IOException, PortletException {
Replace all resourceRequest with actionRequest
UploadRequest should be UploadPortletRequest
Link your action class <portlet-class> to JSP in portlet.xml as,
com.test.docupload.DocumentUploadAction
So, following is the updated code:
Portlet.xml
<?xml version="1.0"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0">
<portlet>
<portlet-name>document</portlet-name>
<display-name>Document Portlet</display-name>
<portlet-class>com.test.docupload.DocumentUploadAction</portlet-class>
<init-param>
<name>view-template</name>
<value>/view.jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<portlet-info>
<title>Document Portlet</title>
<short-title>Document Portlet</short-title>
<keywords>Document Portlet</keywords>
</portlet-info>
<security-role-ref>
<role-name>administrator</role-name>
</security-role-ref>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
<security-role-ref>
<role-name>power-user</role-name>
</security-role-ref>
<security-role-ref>
<role-name>user</role-name>
</security-role-ref>
</portlet>
</portlet-app>
JSP:
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%# taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui" %>
<portlet:defineObjects />
<%#page import="com.liferay.portal.kernel.servlet.SessionMessages"%>
<%# include file="init.jsp" %>
<c:if test='<%=SessionMessages.contains(renderRequest.getPortletSession(),"document-added-success")%>'>
<liferay-ui:success key="document-added-success" message="Document has been added successfully." />
</c:if>
<c:if test='<%=SessionMessages.contains(renderRequest.getPortletSession(),"document-added-failed")%>'>
<liferay-ui:error key="document-added-failed" message="Document Uploaded failed." />
</c:if>
<portlet:actionURL var="addDocActionURL" name="addDoc"></portlet:actionURL>
<aui:form action="<%= addDocActionURL %>" method="post" name="fm" enctype="multipart/form-data">
<aui:input name="title" value="" label="Doc Title"/>
<aui:input name="doc" value="" type="file" label="Select Doc"/>
<aui:button-row>
<aui:button type="submit" />
</aui:button-row>
</aui:form>
DocumentUploadAction:
package com.test.docupload;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.PortletException;
import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.captcha.CaptchaMaxChallengesException;
import com.liferay.portal.kernel.captcha.CaptchaTextException;
import com.liferay.portal.kernel.captcha.CaptchaUtil;
import com.liferay.portal.kernel.dao.jdbc.OutputBlob;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.liferay.portal.kernel.upload.UploadPortletRequest;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
/**
* Portlet implementation class DocumentUploadAction
*/
public class DocumentUploadAction extends MVCPortlet {
public void addDoc(ActionRequest actionRequest, ActionResponse actionResponse) throws IOException, PortletException {
UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(actionRequest);
File docImage = uploadRequest.getFile("doc");
String title = ParamUtil.getString(uploadRequest, "firstName");
InputStream fis = new FileInputStream(docImage);
OutputBlob dataOutputBlob = new OutputBlob(fis, docImage.length());
try {
Doc doc = DocLocalServiceUtil.createDoc(CounterLocalServiceUtil.increment());
doc.setDocName(title);
doc.setOwner(10199);
doc.setData(dataOutputBlob);
doc = DocLocalServiceUtil.addDoc(doc);
if (true) {
SessionMessages.add(actionRequest.getPortletSession(), "document-added-success");
System.out.println("document-added-success");
} else {
SessionErrors.add(actionRequest.getPortletSession(), "document-added-failed");
System.out.println("document-added-failed::");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Passing parameters to Liferay PortletURL

I would like to validate the request of an user by doing he types his personal key. First of all he does the request, now the portlet redirects to a second jsp file where he validates with the key and finally if it is ok the portlet complete the request otherwise returns to the first step.
Here is the code,
1.- view.jsp (the request)
<%# include file="/html/blue/init.jsp" %>
Welcome to our Colors workflow
<br/>
<%
PortletURL redirectURL = renderResponse.createActionURL();
redirectURL.setParameter(ActionRequest.ACTION_NAME, "redirect");
%>
<aui:form name="fmAdd" method="POST" action="<%= redirectURL.toString() %>">
<aui:input type="hidden" name="myaction" value="add" />
<aui:button type="submit" value="Add New Box"/>
</aui:form>
<aui:form name="fmList" method="POST" action="<%= redirectURL.toString() %>">
<aui:input type="hidden" name="myaction" value="list" />
<aui:button type="submit" value="Show All Boxes"/>
</aui:form>
2.- the java code,
public void redirect(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
String action = ParamUtil.getString(actionRequest, "myaction");
PortletURL redirectURL = null;
String redirectJSP = "/checkuser.jsp";
if(action != null) {
String portletName = (String)actionRequest.getAttribute(WebKeys.PORTLET_ID);
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
redirectURL = PortletURLFactoryUtil.create(PortalUtil.getHttpServletRequest(actionRequest),
portletName, themeDisplay.getLayout().getPlid(), PortletRequest.RENDER_PHASE);
redirectURL.setParameter("myaction", action);
redirectURL.setParameter("jspPage", redirectJSP);
}
actionResponse.sendRedirect(redirectURL.toString());
}
3._ checkuser.jsp (the user validate with his key)
<%# include file="/html/blue/init.jsp" %>
<%
PortletURL checkUserURL = renderResponse.createActionURL();
checkUserURL.setParameter(ActionRequest.ACTION_NAME, "checkUser");
String myaction = renderRequest.getParameter("myaction");
%>
<p> Your action: <%= myaction %> </p>
<aui:form name="fm" method="POST" action="<%= checkUserURL.toString() %>">
<aui:input type="hidden" name="myaction" value="<%= myaction %>" />
<aui:input type="text" name="key" value=""/>
<aui:button type="submit" value="Save"/>
</aui:form>
In this phase I am getting the first problem because I do not see the value of the request (myaction variable). This is only for debug.
4._ the java code that catches the last form,
public void checkUser(ActionRequest actionRequest,
ActionResponse actionResponse) throws IOException, PortletException {
String key = ParamUtil.getString(actionRequest, "key");
String action = ParamUtil.getString(actionRequest, "myaction");
String portletName = (String)actionRequest.getAttribute(WebKeys.PORTLET_ID);
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
PortletURL redirectURL = PortletURLFactoryUtil.create(PortalUtil.getHttpServletRequest(actionRequest),
portletName, themeDisplay.getLayout().getPlid(), PortletRequest.RENDER_PHASE);
String redirectJSP = "/view.jsp";
if(key != null) {
if(key.equalsIgnoreCase("blue")) {
if(action != null) {
if(action.equalsIgnoreCase("add")) {
redirectJSP = "/update.jsp";
}
if(action.equalsIgnoreCase("list")) {
redirectJSP = "/list.jsp";
}
}
}
}
redirectURL.setParameter("jspPage", redirectJSP);
actionResponse.sendRedirect(redirectURL.toString());
}
In this phase the portlet always goes to view.jsp where the user does the request. I am thinking both key and action variables are null or at least one of them.
What am I doing wrong?
Regards,
Jose
In Liferay, the parameters are set with a namespace so that they don't cause problems when there are more than 1 portlet on the page. Especially if you have the exact same portlet on the page twice! So when you're setting myaction, it really gets set to something like _myportlet_INSTANCE_xlka_myaction or something similar.
You can use com.liferay.portal.kernel.util.ParamUtil to help you get your parameters without having to worry about the scoping. For example:
ParamUtil.getString(request, "myaction");

"The requested resource was not found" When submitting a form in liferay portlet

I'm developing a liferay portlet. This is not my first time doing that, but a get a simple error that I can't understand why I'm getting this error. When I click submit button I get this error
The requested resource was not found. "http://localhost:8081/addProduct"
It's more than hours I'm trying to solve it and I know that I have made a silly mistake. Can any body help me solve this problem? Any help is appreciated in advance. Here is my jsp code:
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%# taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%# page import="javax.portlet.PortletURL" %>
<portlet:defineObjects />
This is the <b>ServiceBuilderTest</b> portlet.
<portlet:actionURL var="addProduct" name="addProductAction"/>
<aui:form method="post" action="addProduct">
<aui:fieldset>
<aui:input name="productName" label="Product Name"></aui:input>
<aui:input name="userID" label="User ID"></aui:input>
<aui:input name="companyID" label="company ID"></aui:input>
<aui:input name="groupID" label="Group ID"></aui:input>
<aui:input name="serialNumber" label="Serial Number"></aui:input>
<aui:button type="submit" value="Submit"></aui:button>
</aui:fieldset>
</aui:form>
And this is my portlet class code:
public class ServiceBuilderPortlet extends MVCPortlet{
public void addProductAction(ActionRequest actionReauest, ActionResponse actionResponse) throws SystemException, PortalException
{
String productName = actionReauest.getParameter("productName");
String userID = actionReauest.getParameter("userID");
String companyID = actionReauest.getParameter("companyID");
String groupID = actionReauest.getParameter("groupID");
String serialNumber = actionReauest.getParameter("serialNumber");
PRProduct product = PRProductLocalServiceUtil.addProduct(Long.parseLong(companyID), Long.parseLong(groupID), productName,
serialNumber, Long.parseLong(userID));
}
}
make it
<portlet:actionURL var="addProduct" name="addProductAction"/>
<aui:form method="post" action="<%=addProduct%>">
...
actually, I'd see it as best practice to not name the action "addProductAction", but just "addProduct", so the changes would be as such (including one line of java, the rest looks good (visually, not tried/tested):
<portlet:actionURL var="addProduct" name="addProduct"/>
<aui:form method="post" action="<%=addProduct%>">
....
and
public class ServiceBuilderPortlet extends MVCPortlet{
public void addProduct(ActionRequest request, ActionResponse response) throws SystemException, PortalException {
// ...
}
}

Login required twice after logging out due to ViewExpiredException

I have a JSF page on Websphere Process Server (on top of WAS 7) which has ViewExpiredException. When this happens I want the user to be logged out and then logged back in
I've set up a redirect on this exception in web.xml to the following logout page:
<%
session.invalidate();
response.sendRedirect("ibm_security_logout?logoutExitPage=/faces/ToDosOpen.jsp");
%>
Which then redirects to a login page:
<%# page import="com.ibm.wbit.tel.client.jsf.infrastructure.Messages, java.util.Locale" language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<%
String contextPath = request.getContextPath();
Locale locale = request.getLocale();
final String SECURITY_CHECK = "j_security_check";
%>
...
</head>
<body>
...
<h1><%= Messages.getString("LOGIN_LINE", locale) %></h1>
<div class="help-text"><%= Messages.getString("LOGIN_LINE_DESCR", locale) %></div>
<form target="_top" method="POST" action=<%= SECURITY_CHECK %>>
<table id="login-form">
<tr>
<td><%= Messages.getString("LOGIN_NAME", locale) %>:</td>
<td><input type="text" name="j_username"></td>
</tr>
<tr>
<td><%= Messages.getString("LOGIN_PASSWORD", locale) %>:</td>
<td><input type="password" name="j_password"></td>
</tr>
<tr>
<td id="login-button" colspan="2">
<input type="submit" name="login" value="
<%= Messages.getString("BUTTON_LOGIN", locale) %>"></td>
</tr>
</table>
</form>
And when you login you're redirected to the page that caused the exception in the first place. Except what actually happens is the exception is thrown again, and back we go to the login page.
So you have to login twice.
Not sure what to do about this or where to start looking. Any help would be appreciated.
I have looked through existing questions on this and haven't been able to solve it.
EDIT: I've forgotten to mention that this works fine if the action that triggered the exception was a refresh, but fails (having to login twice) if the action was clicking on a commandbar.
Finally solved it using the following ViewHandler.
This basically recreates the view that expired. In the case where there were POST parameters, they've obviously been lost so any view that cannot be created without them needs special handling.
Hopefully this is useful to anyone else who runs into this problem, and please let me know if you see anything wrong with this solution because I am not 100% confident in it.
/**
* This class just handles cases where the session expired
* which causes an exception on reload.
*/
public class ViewExpiredHandler extends ViewHandlerWrapper {
private ViewHandler wrapped;
public ViewExpiredHandler(ViewHandler wrapped) {
this.wrapped = wrapped;
}
#Override
public UIViewRoot restoreView( FacesContext ctx, String viewId )
{
UIViewRoot viewRoot = super.restoreView( ctx, viewId );
try {
if ( viewRoot == null) {
viewRoot = super.createView( ctx, viewId );
ctx.setViewRoot( viewRoot );
}
} catch (Exception e) {
e.printStackTrace();
}
return viewRoot;
}
#Override
protected ViewHandler getWrapped() {
return wrapped;
}
}

Form is not submitted

I wrote a simple JSF form. The problem is that there is a bug that I can't find. When I open the main page and enter the username and password the page must redirect me to the next page but this is not happening. Can you help me to find my mistake?
This is the main login JSF page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:h="http://java.sun.com/jsf/html">
<head>
<title>Login</title>
<link rel="stylesheet" type="text/css" href="resources/css/style.css" />
<script src="resources/js/cufon-yui.js" type="text/javascript"></script>
<script src="resources/js/ChunkFive_400.font.js" type="text/javascript"></script>
<script type="text/javascript">
Cufon.replace('h1',{ textShadow: '1px 1px #fff'});
Cufon.replace('h2',{ textShadow: '1px 1px #fff'});
Cufon.replace('h3',{ textShadow: '0px 1px #000'});
Cufon.replace('.back');
</script>
</head>
<body>
<div class="wrapper">
<div class="content">
<div id="form_wrapper" class="form_wrapper">
<form class="login active">
<h3><center><img src="resources/images/title.png"/></center></h3>
<div>
<label>Username:</label>
<h:inputText value="#{loginController.user}"/>
<span class="error">This is an error</span>
</div>
<div>
<label>Password:</label>
<h:inputSecret value="#{loginController.password}"/>
<span class="error">This is an error</span>
</div>
<div class="bottom">
<h:commandButton label="Login" value="Login" action="#{loginController.user_compare}"/>
<div class="clear"></div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
This is the managed bean
/** Bean for checking users and passwords.
If the user enters the correct username and password
the user will be redirected to main.xhtml
If not the page will refresh. */
package com.dx.sr_57;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named("loginController")
#SessionScoped
public class user_check implements Serializable {
private String user;
private String password;
public user_check(){
}
public user_check(String user, String password){
super();
this.user = user;
this.password = password;
}
/** get the content of the variables from the JSF Login page */
public String setUser(String newValue) {
user = newValue;
return user;
}
public String getUser(){
return user;
}
public String setPassword(String newValue) {
password = newValue;
return password;
}
public String getPassword(){
return password;
}
public String user_compare() {
return "success";
}
}
You need to use a <h:form> component in order to get JSF inputs and commands to work.
So, replace
<form class="login active">
...
</form>
by
<h:form styleClass="login active">
...
</h:form>
You also need to fix your setters to be fullworthy setters, otherwise you might face a PropertyNotFoundException.
So, replace
public String setUser(String newValue) {
user = newValue;
return user;
}
public String setPassword(String newValue) {
password = newValue;
return password;
}
by
public void setUser(String newValue) {
user = newValue;
}
public void setPassword(String newValue) {
password = newValue;
}
Unrelated to the concrete problem, the HTML <center> tag is deprecated since 1998 and invalid in XHTML strict. Remove it. You need to set CSS text-align: center on the <img> instead.

Resources