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

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.

Related

PicketLink EL methods not found

we are using PicketLink 2.7 in an EE7 CDI/JSF app with Wildfly.
According to the PicketLink documentation there are some EL methods
like #{hasRole('ROLE_NAME')}. When we try to use these in an JSF page
<ui:fragment rendered="#{hasRole('ROLE_NAME')}">
we get
Caused by: javax.el.ELException: Function 'hasRole' not found
When we use the EL expression on a CDI bean with
#Restrict("#{hasRole('ROLE_NAME')}")
public void doWhatEver(){}
It works fine (throwing an exception when it doesn't have the role).
So the PicketLink interceptor is configured in beans.xml, we use the uber dependency for PicketLink in the pom file.
What are we missing?
The methods are provided by org.picketlink.internal.el.ELFunctionMethods
as far as I can make out:
public static boolean hasRole(String roleName)
Checks if an authenticated user is granted with a role with the given name.
This method requires that valid ELEvaluationContext associated with the current invation thread.
The EL expressions defined by PicketLink are not available in JSF context. I was facing the same problem and decided to use an #ApplicationScoped bean with the needed methods:
#Named("auth")
#ApplicationScoped
public class AuthorizationManager {
#Inject Identity identity;
#Inject PartitionManager partitionManager;
public void hasRole(String roleName) {
return AuthorizationUtil.hasRole(identity, this.partitionManager, roleName);
}
}
Then you can use it in JSF like:
<ui:fragment rendered="#{auth.hasRole('ROLE_NAME')}">

Liferay MVCPortlet connect FORM actionURL with action

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>

Is it possible intercept a method from #ManagedBean? If not, there alternatives?

I'm new to JSF-2 and CDI (I'm from Spring world).
I want to intercept a method from #ManagedBean but my Interceptor class is never called. Is it possible to do?
LogInterceptor.java
#Interceptor
public class LogInterceptor {
#AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("begin method interceptor");
Object methodReturn = ctx.proceed();
System.out.println("end method interceptor");
return methodReturn;
}
}
RoleMB
#ManagedBean
#ViewScoped
public class RoleMB extends BaseMB {
#Interceptors(LogInterceptor.class)
public void preEditRole(Role role) {
...
}
}
beans.xml
<beans 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/beans_1_0.xsd">
<interceptors>
<class>br.com.preventsenior.services.log.LogInterceptor</class>
</interceptors>
</beans>
The log(InvocationContext ctx) is never called.
Java EE interceptors work only on CDI managed beans and EJBs, not on JSF managed beans.
So, you've basically 2 options:
Change JSF bean management annotations by CDI bean management annotations (#Named et.al.)
Intercept on an EJB method instead which is in turn invoked by JSF managed bean. In a sane Java EE application, the real business logic belongs in EJBs anyway.

jsf and url-pattern of the web.xml file

I am developing a web app using jsf technology. I want a method of my backing bean to be
invoked when the home page of my app is displayed. Usually, a backing bean method
gets involved when a user clicks on a link or a button.
In short I want my backing bean to get some data from the database and send it to the
jsf page, and I want this to occur when a user invokes the home page link
of my app.
Here is how I wanted to solve the problem: use a servlet that is executed when
the expected link is invoked, and call the backing bean from that servlet; but the problem
is I am having some difficulties with the url-pattern of the servlet in the web.xml file. The home page link of my app is: home.jsf. The name of my servlet is
HomeServlet and here is how I configured it in the web.xml file:
<servlet>
<servlet-name>HomeServlet</servlet-name>
<servlet-class>utils.HomeServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HomeServlet</servlet-name>
<url-pattern>/home.jsf</url-pattern>
</servlet-mapping>
So when I run the app, the servlet is executed, but my home.jsf page is empty (completely blank). I don't know why.
So what I want to know is:
Am I using the right approach for this issue?
If yes, which url-pattern should I use?
No, this is definitely not the right approach. You're working your way around JSF. You're supposed to do the job just in the constructor or #PostConstruct method of the request or view scoped JSF managed bean associated with the view.
E.g.
#ManagedBean
#RequestScoped
public class Home {
public Home() {
// Here.
}
#PostConstruct
public void init() {
// Or here. This will be invoked *after* any dependency injections,
// such as #EJB, #ManagedProperty, #Inject, #Resource, etc.
}
// ...
}
Whenever JSF encounters a #{home.someproperty} reference in the home.xhtml (or home.jsp) for the first time, then the bean will just be constructed.
When developing with JSF, you shouldn't have any need to develop other servlets. In JSF, the FacesServlet is the sole servlet which already does all the necessary request/response and model/view controlling job.

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.

Resources