Liferay MVCPortlet connect FORM actionURL with action - liferay

I'm a new user on Liferay. I'm trying to connect my form on the view.jsp:
<portlet:actionURL name="addRule" var="addRuleURL"/>
<aui:form action="<%= addRuleURL.toString() %>" method="post">
.....
With the action in the ActionUtil.java (using Hibernate - Service Builder):
#ProcessAction(name = "addRule")
public void addRule(ActionRequest request, ActionResponse response)
But I can't, Eclipse says:
java.lang.NoSuchMethodException: com.liferay.util.bridges.mvc.MVCPortlet.addRule(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
What can I do to connect my form in the correct way?

I think you are having this problem because you did not include your portlet in portlet.xml, so Liferay eventually uses the default MVCPortlet class which does not have the addRule method. So make sure you have something like this in portlet.xml for your custom MVC portlet:
<portlet-name>yourmvcportlet</portlet-name>
<display-name>Your MVC Portlet</display-name>
<portlet-class>your.portlet.package.YourMVCPortlet</portlet-class>
<init-param>
<name>view-jsp</name>
<value>/jsp/view.jsp</value>
</init-param>

Related

Integrate liferay 7.4 recaptcha with MVC Portlet and apache wicket

I have an old application uses wicket 1.4 and want to integrate the liferay reCAPTCHA ( liferay 7.4).
Is there any guide for that?
Or anyone might help ?
It worked for MVC portlet like the following but still cannot achieve same in wicket :
Use CAPTCHA or reCAPTCHA with custom portlet in Liferay MVC Portlet:
CAPTCHA is a “Completely Automated Public Turing test to tell Computers and Humans Apart”. It is used in the computer world to determine whether an end-user is human or non-human. Liferay provides the necessary API as well as tag library to implement CAPTCHA in your custom portlet. Also, you can integrate Google reCAPTCHA in your custom portlet.
Prerequisites
Java
Liferay portal 7/7.x
Use CAPTCHA in custom portlet
Assuming you’ve already created a Liferay-workspace project
Follow below steps to implement CAPTCHA in your custom portlet
Create MVC Portlet
Go to liferay workspace project → modules → new
Select other → Liferay → Liferay Module Project and Click on Next
Enter project name
Select “Project Template Name” as “mvc-portlet” and Click on “Next”
Enter Package name and Click on “Finish”
The necessary file structure for MVC module will get created as below :
2) Now we add below code in view.jsp
<%# include file="/init.jsp" %>
<%# taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %>
<%# taglib uri="http://liferay.com/tld/captcha" prefix="liferay-captcha" %>
<%# page import="com.liferay.portal.kernel.captcha.CaptchaTextException"%>
<portlet:actionURL name="basicFormDataWithCaptcha" var="basicFormDataWithCaptchaAActionURL" />
<portlet:resourceURL id="captcha" var="captchaResourceURL"/>
<liferay-ui:error exception="<%= CaptchaTextException.class %>" message="captcha-verification-failed" />
<aui:form method="post" name="basicForm" action="<%= basicFormDataWithCaptchaAActionURL %>">
<aui:input name="firstName" >
<aui:validator name="alpha"/>
</aui:input>
<aui:input name="lastName" >
<aui:validator name="alpha"/>
</aui:input>
<liferay-captcha:captcha url="<%= captchaResourceURL %>"/>
<aui:button type="submit" value="Submit"></aui:button>
</aui:form>
3) Create Action method in CustomCaptchaPortlet
package ...;
import ...;
#Component(
...
)
public class CustomCaptchaPortlet extends MVCPortlet {
private Log log = LogFactoryUtil.getLog(this.getClass().getName());
#ProcessAction(name = "basicFormDataWithCaptcha")
public void basicFormDataWithCaptcha(ActionRequest actionRequest, ActionResponse actionResponse)
throws IOException, PortletException {
String firstName = ParamUtil.getString(actionRequest,"firstName");
String lastName=ParamUtil.getString(actionRequest,"lastName");
log.info("First Name : " + firstName);
log.info("Last Name : " + lastName);
try{
CaptchaUtil.check(actionRequest);
log.info("CAPTCHA verification successful.");
}catch(Exception exception) {
if(exception instanceof CaptchaTextException) {
SessionErrors.add(actionRequest, exception.getClass(), exception);
log.error("CAPTCHA verification failed.");
}
}
}
#Override
public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse)
throws IOException, PortletException {
try {
CaptchaUtil.serveImage(resourceRequest, resourceResponse);
}catch(Exception exception) {
log.error(exception.getMessage(), exception);
}
}
protected boolean isCheckMethodOnProcessAction() {
return _CHECK_METHOD_ON_PROCESS_ACTION;
}
private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;}
Output with CAPTCHA
Use Google reCAPTCHA in custom portlet
To integrate Google reCAPTCHA in Liferay please follow below steps
1) Get Site key & Secret key from Google reCAPTCHA
Go to www.google.com/recaptcha in your web browser
Click on “Admin console” button (Located at top-right corner)
Fill up your details in the form and then click on “Submit”
4- You will get “Site key & Secret key” as below image. This you will require while configuring Google reCAPTCHA with Liferay
2) Enable Google reCAPTCHA in your Liferay
Login as admin user
Navigate to Control Panel → System Setting → SECURITY → Security Tools → CAPTCHA
Go to CAPTCHA Engine and change it to reCAPTCHA
Enter “reCAPTCHA public key” and “reCAPTCHA private key”
You need to enter the values you got from Google reCAPTCHA site in previse step , “reCAPTCHA public key” field, and “secret key” in “reCAPTCHA private key” field
Click on ‘Save’
To test Google reCAPTCHA is properly configured or not. Logout from Liferay and go to Create Account page. You can see a default Liferay CAPTCHA is replaced with the new Google reCAPTCHA
3) Use Google reCAPTCHA in your Custom Portlet
Once you configure reCAPTCHA from control panel below, code will render google reCAPTCHA
<liferay-captcha:captcha url="<%= captchaResourceURL %>"/>
If we configure reCAPTCHA from Liferay control panel, Output of above ‘custom-captcha-portlet’ will look like below
As you see it works for MVC portlet but I have some code written in apache wicket which I did not find a way to achieve same and wondering if there is a way to integrate Liferay reCAPTCHA with wicket somehow ?

Prevent remote access of a web page

Is it possible to prevent remote access of a web page?
Let's say I have my page1 (home page) which is obviously accessible anywhere via its url. Then I have page2 (admin page) which I would only like to be accessible from the machine where my web application is deployed.
This may sound like this kind of scenario. Only, instead of the admin console, page2 should not be accessible remotely.
Please be more precise what are you using?
I assume that you don't use any framework, so you have only serlvets and .jsp pages.
First,put you adminpage.jsp to WEB-INF folder. Content of this folder is not visible out of your application (without your permission).
Second, create filter that will intercept your requests to servlets (Try to use servlets for all requests, don't use direct links to .jsp pages, because this is only way to add some security. These servlets should be like controllers in MVC). To create Filter you need to add class that will implement interface Filter
public MyFilter implements Filter {
...
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
if (request.getRemoteAddr.equals("your server address") {
filterChain.doFilter(request,response);
}
}
...
}
You see, if IP address is equal as your server address is, this request will be proceed further. Filter interface has more two methods init() and destroy() and you can leave them blank. To connect your filter with your servlet add to your web.xml following.
<filter>
<filter-name>myFilter</filter-name>
<filter-class>fullPackagePath.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/url-to-the-admin-panel-servlet</url-pattern>
</filter-mapping>
Of course you need to have servlet with url that will forward to the admin.jsp page.

Liferay/Icefaces portlet doesn't allow to access in doView methods

I have a problem with the access at the doView() methods.
I've made up a portlet using Liferay 6.3 as CMS, ICEFACES 3.3.0 and tomcat 7. I used a liferay-faces-bridge in order to use Icefaces framework in Liferay. For this reason i have setted up the portlet.xml in this way:
<portlet>
<portlet-name>FinalTest</portlet-name>
<display-name>FinalTest</display-name>
<portlet-class>org.portletfaces.bridge.GenericFacesPortlet</portlet-class>
<init-param>
<name>javax.portlet.faces.defaultViewId.view</name>
<value>/index.xhtml</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<portlet-info>
<title>FinalENELTest</title>
<short-title>FinalENELTest</short-title>
<keywords>FinalENELTest</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>
Also I have a ManagedBean like this (for the business logic):
#ManagedBean(name="backingBean")
#SessionScoped
public class BackingBeanImpl extends GenericPortlet{
....
#Override
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
// TODO Auto-generated method stub
System.out.println("I'M HERE");
super.doView(request, response);
}
}
The problem is that when the portlet starts the doView() method is not invoked. Maybe it is a bridge problem. I don't know.
I hope someone can help me.
Thanks
Your portlet implementation - according to the portlet.xml that you list - is org.portletfaces.bridge.GenericFacesPortlet. Just because your backing bean implements GenericPortlet does not make it the portlet's implementation. doView is implemented in the referenced portlet, not in your class.
If you want to override GenericPortlet methods, you shouldn't use JSF. Corollary of that: If you use JSF, use the JSF style controllers to access your business logic.
By the way: You shouldn't put your business logic into a portlet, rather make the portlet access your business logic. Don't have your business logic reference the portlet api: That would restrict your business logic to run only in that environment.

Configure web service in seam ("no active application context")

I am building a web service using seam 2.0.1 and deploying it on jboss 4.2.2 GA. I have my web service class which access another class (updates stuff in data base).
I have standard-jaxws-endpoint-config.xml in META-INF folder.
#Name("pluginHandler")
#Scope(ScopeType.APPLICATION)
#Install(precedence = Install.BUILT_IN)
#Startup(depends = "someclass")
#Stateless
#WebService(name = "Plugin", serviceName = "PluginService")
public class PlugInHandler {
#WebMethod
public int processRequest(Account account)
{
Workbench wb = Component.getInstance("Workbench");
//above line keeps throwing exception "No application context active"
}
}
I have been looking all over different forums, but I cannot find a solution. I tried using Lifecycle.begincall() and Lifecycle.endCall() but nothing worked.
Do I need web.xml as well? If yes what information should web.xml contain?
Any help would be highly appreciated.
I recognize that this is question is rather dated, but to those few poor souls out there that still share your (and, currently my) predicament, here are a few pointers (dragged together from various sources but mainly from https://community.jboss.org/thread/192046):
Java EE WebService
First, using JBoss 4.2.2 likely means using Java EE5. WebServices there (with or without SEAM 2) can only be created on top of Stateless Session Beans. Stateless Session Beans in Java EE 5 need to implement a Service Endpoint Interface annotated with #Local or #Remote. While this has become optional in Java EE6, it is still mandatory here.
So:
#Local
public interface PluginHandlerInterface {
int processRequest(Account account);
}
#WebService
#Stateless
public PluginHandler implements PluginHandlerInterface { }
POJO WebService
If, in seam, you want to use a regular POJO as web-service, your class has to have another special annotation defining a Handler chain:
#WebService
// This here makes all the difference!
#HandlerChain(file = "web-service-handler-chain.xml")
public class PluginHandler {
...
}
This is the handler chain you put in /WEB-INF/classes/web-service-handler-chain.xml:
<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<description>seam request handler</description>
<!-- probably not necessary
<handler-name>org.jboss.seam.webservice.SOAPRequestHandler</handler-name>
-->
<handler-class>org.jboss.seam.webservice.SOAPRequestHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
And you have to announce your service class to the war files web.xml like so:
<listener> <!-- this might already be present in your web.xml -->
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
<servlet> <!-- Which class is to be used? -->
<servlet-name>PluginHandler</servlet-name>
<servlet-class>your.package.name.PluginHandler</servlet-class>
</servlet>
<servlet-mapping>
<!-- you'll find it under http://localhost:8080/your-war/PluginHandler?wsdl-->
<servlet-name>PluginHandler</servlet-name>
<url-pattern>/PluginHandler</url-pattern>
</servlet-mapping>
So these three steps, creating the handler chain, adding the annotation and announcing your service to the web.xml, should do the trick for you in SEAM: You'll have a web-service and the SEAM Context available right in it.

Xhtml pages and HttpSession test , no jstl?

I have a dynamic web application in Java EE with JSF, Facelets, Richfaces.
My pages are all xhtml pages.
So JSTL isn't working in it.
For my account pages and all other private pages to be reachable, I want to test if the user got connected, so if the attribute session in HttpSession is not null. If it's null, the user gets redirected in the welcome page.
I tried in my xhtml page :
<jstl:if test="${sessionScope['session']==null}">
<jstl redirect...>
</jstl:if>-->
but as it's not jsp page it won't work. So where am I supposed to test if the session is not null to allow the user to see his private pages ?
in a central managed bean ?
The normal place for this is a Filter.
Create a class which implementsjavax.servlet.Filter and write the following logic in the doFilter() method:
if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
// Not logged in, so redirect request to login page.
((HttpServletResponse) response).sendRedirect("/login.jsf");
} else {
// Logged in, so just continue request.
chain.doFilter(request, response);
}
Map this filter in web.xml on an url-pattern of something like /private/*, /secured/*, /restricted/*, etc.
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.example.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/private/*</url-pattern>
</filter-mapping>
If you have the private pages in the /private folder then this filter will be invoked and handle the presence of the logged-in user in the session accordingly.
Note that I renamed attribute name session to user since that makes much more sense. The HttpSession itself is namely already the session. It would otherise been too ambiguous and confusing for other developers checking/maintaining your code.

Resources