I am unable to access GET parameters in a backing bean. The example.xhtml file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:metadata>
<f:viewParam name="id" value="#{myBackingBean.unitId}" />
<f:viewAction action="#{myBackingBean.findUnits}" />
</f:metadata>
<head>
<title>Example Title</title>
</head>
<body>
I found #{myBackingBean.units.size()} units.
</body>
</html>
My understanding is that when I GET example.jsf?id=3 then JSF calls myBackingBean.setUnitId(3). Correct?
Here is MyBackingBean:
#Model
public class MyBackingBean {
private static Logger logger = Logger.getLogger(MyBackingBean.class
.getName());
//#ManagedProperty("#{param.id}")
private Long unitId;
#Inject
private IExampleEJB myExampleEjb;
private List<Unit> units;
#PostConstruct
public void postConstruct() {
Map<String, String> mymap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
for (String k:mymap.keySet()) {
logger.info(String.format("%s %s", k,mymap.get(k)));
}
}
public void findUnits() {
logger.info(String.format("MyBackingBean findUnits %d", unitId));
units = myExampleEjb.findUnits();
}
public List<Unit> getUnits() {
return units;
}
public void setUnits(List<Unit> units) {
this.units = units;
}
public Long getUnitId() {
return unitId;
}
public void setUnitId(Long unitId) {
this.unitId = unitId;
}
}
The id parameter is in the parameter request map in postConstruct().
In my case, setUnitId() is never called, nor is findUnits().
In a different but related question, the #ManagedProperty (currently commented out) does not work either.
Given the xmlns.jcp.org namespace, you're using JSF 2.2. The early Mojarra 2.2.0 and 2.2.1 versions have a known bug which causes the <f:viewParam> to not work.
As per the comments you're using GlassFish 4.0. If you didn't upgrade its bundled JSF implementation and thus are using the early Mojarra version 2.2.0, then you're definitely facing this bug and you need to upgrade.
You can get the JAR from http://javaserverfaces.java.net. All you need to do is to replace javax.faces.jar file in GlassFish's /modules folder with the newer version.
See also
f:viewParam doesn't pass required parameter when new xmlns.jcp.org namespace is used
Related
I'm using poll from primefaces to update an image every n seconds. I'm flipping between two images right now just to make sure it's working. Now what I'm trying to do is display images that aren't stored on the server. I wrote a class that snaps a photo every n seconds. I don't want to save it to disk to reduce IO. So I'd like to do something like the following flow
#ManagedBean
#ViewScoped
public class myClass implements Serializable {
public Object getImage() {
Object newImage = MyClass.takePhoto();
return newImage;
}
public void increment() {
}
}
XHTML:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form>
<h:graphicImage value="#{myClass.image}" id="img" cache="false"/>
<p:poll interval="1" listener="#{myClass.increment}" update="img" />
</h:form>
</h:body>
</h:html>
So my question is, is it possible to return an Image object to h:graphicImage in a similar way to the pseudo-code above?
Yes, try using the Primefaces StreamedContent class to provide a stream to graphicImage, rather than an object.
Something like:
public StreamedContent getImageStream() {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(myBufferedImage, "png", os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
return new DefaultStreamedContent(is, "image/png");
}
Then in your JSF page:
<p:graphicImage value="#{myController.imageStream}" cache="false"/>
Note that this uses p:graphicImage, rather than h:graphicImage.
I am developing a simple application on JSF having the following dependences
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>2.0.2</version>
</dependency>
and being a simple page with it backing bean.
xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<title></title>
</head>
<body >
<h:form>
<f:view >
<h:commandButton id="otxMainPanelTextBt" value="click"
action="#{otherController.doSome}"/>
</f:view>
</h:form>
</body>
</html>
Java code
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean(name = "otherController")
#ViewScoped
public class Other implements Serializable {
private static final long serialVersionUID = -6493758917750576706L;
public String doSome() {
System.out.println(this);
return "";
}
}
If I click on the commandButton many times according to toString source code it should write
class name+hashCode
but it writes something like the following
de.controller.Other#118ea91
de.controller.Other#1e8f930
de.controller.Other#1a38f3c
So, everytime we click there is a different hashcode for the viewscoped bean. Is this incorrect? I have tryed with session beans and this doesn't happen.
EDIT
I modified the class following #BalusC suggestion in the following way.
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean(name = "otherController")
#ViewScoped
public class Other implements Serializable {
private static final long serialVersionUID = -6493758917750576706L;
#PostConstruct
public void init()
{
System.out.println("Post Construction");
}
public Other()
{
System.out.println("Constructor");
}
public void doSome() {
System.out.println(this);
}
}
And I found this output after clicking many times.
Constructor
Post Construction
de.controller.Other#b748dd
de.controller.Other#1620dca
de.controller.Other#116358
de.controller.Other#73cb2d
de.controller.Other#1cc3ba0
So, the constructor and PostConstructor Methods are invoked only once, and in spite of this the object still has a different hashcode in every call. This is weird because the constructor with no parameter is supposed to be called on a managed bean instantiation, but it is not, so i still don't understand how can be the object created several times?
When you return non-null from an action method, a new view is created.
If you want to keep the current view alive, just return null or void from the action method.
E.g.
public void doSome() {
System.out.println(this);
}
See also:
How to choose the right bean scope?
That said, your conclusion that this is a problem is correct, but the grounds on which you based off your conclusion, "incorrect hashcode implementation", makes no utter sense. It were just physically different bean instances everytime. Add a default constructor to the class, put a breakpoint on it and you'll see that it's invoked everytime after you returned from the action method, creating a brand new instance.
i am learning struts2 and facing some problems with showing the addFieldError message..nothing shows up ..
when i run my project and leave userID field blank it does enters into the validate method and even satisfies the condition of isEmpty method but it doesnt shows up any error message..
i put a s.o.p. statment in the isEmpty method to see ,it is entering or not..
the statment gets printed on console , the url changes to ../MyStruts/validation.action with no errors anywhere and nothing happens further..
can someone tell me where i am doing it wrong..
here is my code..
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="validate" extends="struts-default">
<action name="validation" class="com.staction.DataAction">
<result name="success">/success.jsp</result>
<result name="input">/form1.jsp</result>
<result name="error">/error.jsp</result>
</action> </package>
</struts>
form1.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
</head>
<s:form action="validation">
<h1>
<s:textfield label="UserName" name="userID" />
<s:password label="password" name="password" />
</h1>
<s:submit />
</s:form>
<s:a href="forget">forget password </s:a>
</html>
Action class...
package com.staction;
import org.apache.commons.lang3.StringUtils;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class DataAction extends ActionSupport implements ModelDriven<User> {
private static final long serialVersionUID = 1L;
User user;
DataCheck dc;
public DataAction() {
user=new User();
dc=new DataCheck();
}
#Override
public void validate() {
if(StringUtils.isEmpty(user.getUserID()))
{
System.out.println("hellp");
addFieldError("user.userID", "wtf!!!!");
}
}
public String execute()
{
System.out.println("user.userID");
/* if(dc.isValid(user))
{
return SUCCESS;
}*/
return ERROR;
}
#Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
}
and finally the User class..
package com.staction;
import org.apache.commons.lang3.StringUtils;
import com.opensymphony.xwork2.ActionSupport;
public class User{
String userID;
String password;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Your form:
<s:textfield label="UserName" name="userID" />
Your field error:
addFieldError("user.userID", "wtf!!!!");
See the difference?
Also:
I hope your code isn't actually formatted randomly like that; it's very difficult to read.
Why does your User class extend ActionSupport? If it's not an action, don't extend the base default action: it's pointless, and misleading.
Consider naming actions something meaningful: most actions are "data actions".
When posting examples, kindly trim out commented-out code and stuff that isn't directly related to the specific question.
In addition to response of Dave Newton, you must delete "user." in addFieldError so that Struts2 takes automatically the right object using getModel, or you must add set/get methods for object user in Action so that object is accessed using getter.
Jst use the name of your field that to be validated... Change ur code to
addFieldError("UserName", "wtf!!!!");
I have the following scenario:
Struts.xml
<action name="user_initNews" method="initNews" class="it.sba.bcc.sbarima.user.web.action.UserAction">
<result type="dispatcher">
<param name="location">pages/elementicomuni/elencoNews.jsp</param>
</result>
</action>
User Action
public class UserAction extends BaseAction
{
private NewsService newsService = null;
private User utente;
private List<News> news;
public String initNews()
{
return SUCCESS;
}
public void elencoNews()
{
try
{
newsService = UserServiceFactory.getNewsService();
this.news = newsService.getNews(getAbiUserProfile(), getMatricolaUserProfile());
}
catch (ServiceException e)
{
e.printStackTrace();
}
}
public List<News> getNews()
{
return news;
}
}
elencoNews.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<?xml version="1.0" encoding="utf-8"?>
<%# taglib uri="/struts-tags" prefix="s" %>
<html>
<body>
<s:action name="user_elencoNews!elencoNews"></s:action>
<s:iterator value="news" var="n">
<label><s:property value="descrizione"/></label>
</s:iterator>
</body>
</html>
Whene the elencoNews.jsp is rendered, I would like to call from the JSP page an action thath return a set of POJO to iterate.
The elencoNews.action is correctly called, but I do not know how to treat data on the elencoNews.jap
How can I do that?
I'm afraid you are misunderstanding the whole Struts2 typical workflow. You dont (typically) want to call another action from the JSP, in the typical workflow the JSP renders after your action has processed your request, and it just displays data (typically from your Action instance, which is found in the value stack).
Eg read here
In your example, you'd should code in your JPS:
<s:iterator value="news" var="n">
<s:property value="descrizione"/>
</s:iterator>
If you have this concepts clear (and you have coded the most basic-typical struts2 cases), the disregard this and be more explicit about what are you trying to accomplish - why you have two actions involved for a single request and jsp.
If you want a dynamic jsp page, you can look into using the Struts2-jQuery plugin which will allow you to call another action in your JSP and load the results. See examples at http://www.weinfreund.de/struts2-jquery-showcase/index.action under Ajax Link or Ajax Div sections.
Has anybody used JSF2, PrimeFaces, and Highcharts together?
I am really confused on how I should put all these together, specially regarding the ajax request to get the data from the server to feed into Highcharts on the view to update the chart.
What I have right now is a servlet that handles the Ajax request, which is sent using JQuery.ajax() method and use JQuery to update the chart with the new data received as JSON object. And I am using GSon.toJSon to convert Java object into JSON object.
What I am trying to achieve here is that I want to replace that servlet with the JSF2. Instead of using a different servlet, I want to use JSF and have some backing bean to prepare and send the JSON object to the client.
Anybody?
In the example below the the p:commandButton starts the ajax request. The JSON object you want to use can be stored in the h:inputHidden field. When the p:commandButton completes the javascript function is called to update the chart. The javascript function will be able to access the JSON object from the h:inputHidden field.
xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<script type="text/javascript">
function dosomething() {
var value = jQuery("#beanvalue").attr('value');
alert(value);
}
</script>
</h:head>
<h:body>
<h:form prependId="false" >
<p:commandButton value="update" action="#{testBean.update}" update="beanvalue" oncomplete="dosomething();" />
<h:inputHidden value="#{testBean.output}" id="beanvalue" />
</h:form>
</h:body>
</html>
Bean
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TestBean {
private String output;
public TestBean() {
output = "1";
}
public void update() {
output += "1";
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
}