Does f:attribute support other things than String? - list

I have the need to implement an ice:commandButton that passes a list to its backing bean. I'm not in a portlet scope, but in a tag scope.
I know that when I retrieve an f:attribute from the actionListener I get an object that has to be casted.
I want to know if I can map f:attribute to a List<MyClass>, where the actual instance of the list is actually an ArrayList and MyClass is serializable.
Something like:
MyTag.xhtml
<ice:commandButton actionListener="#{TagBean.doPrintItems}">
<f:attribute name="collection" value="#{items}" />
</ice:commandButton>
//[other things]
MyPortlet.jspx
<my:printPopup items="#{BackingBean.itemsToPrint}" />
BackingBean.java
class BackingBean {
private List<MyClass> itemsToPrint;
//getter and setter of course
}
TagBean.java
class TagBean {
private List<MyClass> collection;
//getter and setter of course
public void doPrint(ActionEvent e) {
collection = (List<MyClass>) e.getComponent().getAttributes().get("collection");
}
Do you think this is feasible? Thanks

The <f:attribute> gives you the possibility to add custom component attributes. They will be stored in the component tree state in the server side. So it can be any Java object type you want. The method UIComponent#getAttributes() also hints that less or more; it returns a Map<String, Object>, not a Map<String, String>. I believe your doubt is based on the fact that HTTP request parameters can only be strings. But component attributes should not be confused with HTTP request parameters.

Related

Mapping #Json property with JDBI

According to JDBI document https://jdbi.org/#_jackson_2, it seems that it's quite straight forward to have a json property of your object model, however I've tried the following and it ran into many issues.
DB: Postgres with a column type of Jsonb
class Event {
private String name;
#Json
private EventProperty jsonProperty;
...
}
Datasource has been configured with
#Bean
public Jdbi jdbi(TransactionAwareDataSourceProxy eventStoreTxAwareDataSourceProxy) {
Jdbi jdbi = Jdbi.create(eventStoreTxAwareDataSourceProxy);
jdbi.installPlugin(new PostgresPlugin());
jdbi.installPlugin(new Jackson2Plugin());
}
SQL for binding list of insertion
INSERT INTO event (name, json_property)
VALUES (
:name,
:jsonProperty)
When running the code to insert, the following error occurred:
org.jdbi.v3.core.statement.UnableToCreateStatementException: no argument factory for type com.EventProperty [statement:"INSERT INTO event (...]
If I created EventPropertyArgumentFactory and using Jackson ObjectMapper and writeValueAsString then I can save it to DB. However, when retrieving it back from DB by
try (Handle handle = jdbi.open()) {
EventDao dao = handle.attach(EventDao.class);
return dao.findByName(name);
}
throws the following errors
java.lang.ClassCastException: Cannot cast org.postgresql.util.PGobject to com.EventProperty
I thought all I needed to do is declare the field annotated with #Json, the DB column has to be json/jsonb type and install the plugins, but seems like this is not the case?
Anyone has tried this successfully, without having to define custom row mapper and argument factory implementation?
Thanks
The documentation says:
// use #Json qualifier:
...
// also works on bean or property-mapped objects:
class MyBean {
private final MyJson property;
#Json
public MyJson getProperty() { return ...; }
}
I've checked and it's unfortunate but #Json only works when placed on a property( i.e. getter or setter) and not on a field.
You can make your work easier if you use Lombok library.
Modify lombok.config file by adding this line:
lombok.copyableannotations += org.jdbi.v3.json.Json
Now in bean declaration you can do this:
#Data // will generate setters and getters among other things
class Event {
private String name;
#Json // will be copied onto getter and setter due to config change we made
private EventProperty jsonProperty;
...
}
Have fun!
Not sure if you've figured this out by now but I just ran into this same issue and finally figured it out.
Basically, you just have to add the annotation on the getter or setter of the class, not the top-level field.
class Event {
private String name;
private EventProperty jsonProperty;
...
#Json
public getEventProperty() {
return jsonProperty;
}
}

How can I invoke *this* on a JRBeanCollectionDataSource?

I am passing a list of images to my report. I want to render it inside a List object in the report.
I have used JasperReports lists before and I'm aware that I can reference each field of an element in a list using the $F{} tag, but how can I reference the element of the list itself?
Basically i would like to use something like $F{this}, or $F{self}. Is there such a thing?
Yes, you can use the alias _THIS.
The quote from the JasperReports Ultimate Guide:
A special field mapping can be used to access the current JavaBean object itself. Thus, when a field uses _THIS as description or name, the data source will return the current JavaBean object as field value. This is useful when the report needs to extract from the current object some data that does not correspond to a property that follows JavaBeans standards (for instance, the data is returned by a method that takes some arguments), or when the current object needs to be passed to as argument to a method called in one of the report expressions.
The sample of using _THIS
The snippet of jrxml file:
<subDataset name="dataset1">
<field name="city" class="java.lang.String">
<fieldDescription><![CDATA[_THIS]]></fieldDescription>
</field>
</subDataset>
The snippet of JavaBean:
public class AddressBean {
private String city;
private Integer id;
private PersonBean person;
public AddressBean getAddress() {
return this;
}
public String getCity() {
return city;
}
public Integer getId() {
return id;
}
The JasperReports Ultimate Guide is here.
You can also read the answer by GenericJon on How to access the root element of the datasource in jasperreports question.

Web Service Class of AS in Flex 4

I am trying to receive data from the Web Service and I am getting the Data from Web Service back but it is form of [object Object]. Can anybody help me on this.
Below is the code for my web service:
public class WebServiceAccess
{
private var webService:WebService;
private var serviceOperation:AbstractOperation;
private var myValueObjects:ValueObjects;
private var method:String;
[Bindable]
public var employeeData:ArrayCollection;
[Bindable]
public var employees:ArrayCollection;
public function WebServiceAccess(url:String, method:String)
{
webService = new WebService();
this.method = method;
webService.loadWSDL(url);
webService.addEventListener(LoadEvent.LOAD, ServiceRequest);
}
public function ServiceRequest():void
{
serviceOperation = webService.getOperation(method);
serviceOperation.addEventListener(FaultEvent.FAULT, DisplayError);
serviceOperation.addEventListener(ResultEvent.RESULT, DisplayResult);
serviceOperation.send();
}
public function DisplayError(evt:FaultEvent):void
{
Alert.show(evt.fault.toString());
}
public function DisplayResult(evt:ResultEvent):void
{
employeeData = evt.result as ArrayCollection;
Alert.show(employeeData.toString());
}
}
First of all, evt.result is not an ArrayCollection, it is an Object (unless your SOAP service/WSDL are completely screwed up/malformed XML).
Second, you can't just display an Array or ArrayCollection (or generic Object, even) as a String (even though the .toString() method always seems to imply that) anyway, you have to parse the data to get what you want from it.
Now, the WebService class is nice in that it automatically parses the XML file that a SOAP service returns into a single usable Object. So that is actually the hard part.
What you need to do is call various properties of the object to get the data you need.
So if the XML return (look at your WSDL to see what the return should be, I also highly suggest soapUI) is this:
<employee name="Josh">
<start date="89384938984"/>
<photo url="photo.jpg"/>
</employee>
And you wanted to display "Josh" and the photo, you would do this.
var name:String = e.result.employee.name;
var url:String = e.result.employee.photo.url;
It does get more complicated. If the WSDL allows for multiple nodes with the same name at the same level, it does return an ArrayCollection. Then you have to loop through the array and find the exact item you need.
Just remember: The WSDL is god. Period. If it says there can be multiple "employee" nodes, you have to code accordingly, even if you don't see more than one in your tests. The issue is that there always could be multiple nodes.

get # String parameter from url

how can I get certain parameter from url directly from struts2?
http://apps.facebook.com/testApp/myaction.action#param1=a1afacf5&param2=AAADpzov7PBMBA
Previously, getting param1 and 2 from javascripts in JSP using window.location.href.slice. Now I want to get those params directly from action class. I tried to get those using request.getParameter("param1"), but getting null.
All you need to create property in your action class and provide there getter and setters,once this is done framework will push them in to the ValueStack with action processing.
OGNL expression will help you to access the properties being there in the Value-Stack.You have to do something like
Action Class
public class MyAction extends ActionSupport{
private String param1;
private Sting param2;
// provide getter and setters for the above properties
public String execute() throws Exception{
// your action logic and provide param1,param2 values which you want in you JSP
return SUCCESS;
}
}
once you action get called both the parameters will be pushed to value stack with the values you have provided in the action class,all you need to access them in your JSP with OGNL like
JSP page
<s:property name="param1" value="param1"/>
<s:textfiled name="param2" value="%{param2}"/>

Web Service: Specifying XML Serialization element names for generic types

I've created a web service that uses a generic type Response<TCode, TData> and so I'm ending up with elements like
ResponseOfResponseCodeUserData
ResponseOfResponseCodeArrayOfRightData
etc.
Functionally works just fine but I'm wondering if there's a way to name these particular elements?
EDIT:
Here's an example.
[return: XmlElement("AuthenticationResponse")]
[WebMethod]
public Response<ResponseCode, AuthenticationData> AuthenticateProcess(string ProcessName, string Password)
{
// ... Code ...
}
Still returns
<ResponseOfResponseCodeAuthenticationData (...) >
Any ideas?
It might help if you were to show some code.
Still, look at the [XmlElementAttribute] attribute, which allows you to specify the element name. If your issue is with return values, then you will need to use
[return: XmlRoot("ReturnElementName")]
[WebMethod]
public int MyWebMethod() { ... }