jsf and url-pattern of the web.xml file - jsf

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.

Related

Display menu items depending on user roles defined in web.xml

I have my own realm classes extends AppservPasswordLoginModule and AppservRealm where I get user and roles from my own table in database. In web.xml I defined access to pages and it works.
I have some mechanism to read main menu from my menu.xml file in my bean with #SessionScoped annotation.
I want to use rules from web.xml to display only this items, which user has acces to (defined in web.xml), without repeating configuration in my menu.xml file.
I imagine that the solution might be to check the access to the page when I create menu item for this page in my SessionScoped bean, but I don't know how it could be checked easily.
What is the best solution for this situation?
I'm using glassfish 4.1 and jsf 2.2.
I solved this by the following method:
In my ServletListener
#WebListener
public class implements ServletListener ServletContextListener {...}
I read security-constraint from web.xml, parsing them and store it in my #ApplicationScoped bean.
In #SessionScoped bean, in #PostConstruct annotated method I get all roles stored in #ApplicationScoped bean and checked each individual by
FacesContext.getCurrentInstance().GetExternalContext().IsUserInRole(role);
method.
So I have all current user roles. Then, in my #SessionScoped bean, for each menu item I check whether the resource represented by the url of this menu item is available for roles that current user has.
EDIT: The bad side of this solution is that I analyzing the web.xml file only, without annotations

How can I get all view scope managed beans for the current ViewRoot?

I have to implement some bean post processor for all view scope managed beans on the page. I have implemented SystemEventListener with PostConstructViewMapEvent as system-event-class. How can I get all view scope managed beans for the current ViewRoot? viewRoot.getViewMap() returns empty map (Mojarra JSF 2.1.19), but I have a few managed beans with view scope. Of course I can invoke my post processor in #PostConstruct method in every such bean, but is there a global solution like in Spring Framework?
My faces-config.xml configuration:
<application>
<system-event-listener>
<system-event-listener-class>com.myapplicationname.ViewScopeBeanPostProcessor</system-event-listener-class>
<system-event-class>javax.faces.event.PostConstructViewMapEvent</system-event-class>
<source-class>javax.faces.component.UIViewRoot</source-class>
</system-event-listener>
</application>

ViewScoped after redeploy server

I have strange problem on my simple form in JSF 2.0. In this form, I use two selects, if the first select is chosen, the second should be reload with new options. I use the same mechanism as on Primefaces demo page : Primefaces demo page. My bean is #ViewScoped. I also run my app on jetty-maven plugin by "mvn jetty:run". No problem so far. My form works well.
The problem occurs when I change something while my server is running, jetty is reloading. And after that these two selects don't work - if I choose option on the firts one, second one isnt responding. I have to clear all session by logout in Spring Security and after that my form come back to work.
When i changed my bean to #SessionScoped, problem disappeared.
Is this working proper? I dont want to have my form on session scoped, I prefer ViewScoped.
Try to check your context is postback like this on postConstruct in your bean.
#PostConstruct
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
//Write your code here...
}
Or try close to partial state saving on your web.xml if jsf version is 2.0, but with this method, your application may need more memory allocation
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
Good Luck!

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