I have a java bean class 'MenuItem' which consist of list of children .
I want to display iterate and render through this object in jsp and display the menu tree.
I tried the json data creation, but it needs ajax call. And in my case, I need to submit the page instead of ajax.
I am using struts 2. Can anyone please suggest how can I render and iterate through my bean object in jsp ?
Thanks in Advance.
Here is my Menu bean object:
public class MenuItem implements Serializable {
private static final long serialVersionUID = 8690828081102943225L;
private Long id;
private String name;
private Collection<MenuItem> children;
private String url;
private String actionHoverLabel;
private String actionLabel;
private Long displayOrder;
private Boolean isLeaf;
private Boolean isVisible;
private Long menuLevel;
private Long parentId;
public String getActionHoverLabel() {
return actionHoverLabel;
}
public void setActionHoverLabel(String actionHoverLabel) {
this.actionHoverLabel = actionHoverLabel;
}
public String getActionLabel() {
return actionLabel;
}
public void setActionLabel(String actionLabel) {
this.actionLabel = actionLabel;
}
public Long getDisplayOrder() {
return displayOrder;
}
public void setDisplayOrder(Long displayOrder) {
this.displayOrder = displayOrder;
}
public Boolean getIsLeaf() {
return isLeaf;
}
public void setIsLeaf(Boolean isLeaf) {
this.isLeaf = isLeaf;
}
public Boolean getIsVisible() {
return isVisible;
}
public void setIsVisible(Boolean isVisible) {
this.isVisible = isVisible;
}
public Long getMenuLevel() {
return menuLevel;
}
public void setMenuLevel(Long menuLevel) {
this.menuLevel = menuLevel;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public MenuItem() {
children = new ArrayList<MenuItem>();
isVisible = true;
}
public MenuItem(Long id, String name) {
this.id = id;
this.name = name;
children = new ArrayList<MenuItem>();
isVisible = true;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Collection<MenuItem> getChildren() {
return this.children;
}
public void setChildren(Collection<MenuItem> children) {
this.children = children;
}
public boolean isLeaf() {
if (children != null && children.size() > 0) {
return false;
} else {
return true;
}
}
public void addChild(MenuItem child) {
if (child != null && children != null) {
children.add(child);
child.setParentId(this.getId());
}
}
public void removeChild(MenuItem child) {
if (child != null && children != null) {
children.remove(child);
child.setParentId(null);
}
}
public void setUrl(String url) {
this.url = url;
}
public String getUrl() {
if (url == null) {
return name;
} else {
return url;
}
}
#Override
public boolean equals(Object obj) {
MenuItem m = null;
boolean isEqual = false;
if (id != null && id >= 0) {
m = (MenuItem) obj;
if (m.getId().equals(id)
isEqual = true;
} else {
isEqual = super.equals(obj);
}
return isEqual;
}
#Override
public int hashCode() {
if (id != null && id >= 0) {
return id.hashCode();
} else {
return super.hashCode();
}
}
#Override
public String toString() {
return "name: " + name + " id: " + id;
}
If you want to operate on the bean in JSP, you can very well do that with struts tags. The bean has to be in the scope.
Why do you need JSON in this case?
If you still want JSON, the check for GSON library and Jackson mapper library.
On the JSP, you can store the JSON object in a variable and then operate on that.
On page submit Struts action would form the JSON and then set it in a page bean variable.
Go to www.json.org
Download Java Library for JSON encoding.
Compile it (build a jar for convenience).
Write a method alike this to JSON Serialize your bean:
public static String toJson(SomeBean bean)
{
JSONObject jo = new JSONObject(bean);
return jo.toString();
}
Deserialization is a little tricky but should work like:
JSONObject jo = new JSONObject(jsonString);
SomeBean res = new SomeBean();
res.someProperty = jo.getString("someProperty");
res.someIntProperty= jo.getInt("someIntProperty");
Obviously you have to take care of complex properties, but for simple beans it should work out like a charm.
Straight from sources:
/**
* Construct a JSONObject from an Object using bean getters.
* It reflects on all of the public methods of the object.
* For each of the methods with no parameters and a name starting
* with <code>"get"</code> or <code>"is"</code> followed by an uppercase letter,
* the method is invoked, and a key and the value returned from the getter method
* are put into the new JSONObject.
*
* The key is formed by removing the <code>"get"</code> or <code>"is"</code> prefix.
* If the second remaining character is not upper case, then the first
* character is converted to lower case.
*
* For example, if an object has a method named <code>"getName"</code>, and
* if the result of calling <code>object.getName()</code> is <code>"Larry Fine"</code>,
* then the JSONObject will contain <code>"name": "Larry Fine"</code>.
*
* #param bean An object that has getter methods that should be used
* to make a JSONObject.
*/
public JSONObject(Object bean) {
this();
this.populateMap(bean);
}
Are you sure you've everything set up correctly (Classpath) ?
Related
I have a problem with Spring Boot.
I am making a REST application, and I have a service that returns a Map(Share, Integer)
Share is a class written by me:
public class Share {
private String ticker;
private String name;
private Double value;
public Share() {
super();
}
public Share(String ticker, String name, Double value) {
super();
this.ticker = ticker;
this.name = name;
this.value = value;
}
public String getTicker() {
return ticker;
}
public void setTicker(String ticker) {
this.ticker = ticker;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getValue() {
return value;
}
public void setValue(Double value) {
this.value = value;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((ticker == null) ? 0 : ticker.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Share other = (Share) obj;
if (ticker == null) {
if (other.ticker != null)
return false;
} else if (!ticker.equals(other.ticker))
return false;
return true;
}
#Override
public String toString() {
return "Share [ticker=" + ticker + ", name=" + name + ", value=" + value + "]";
}
}
And the #RestController is:
public class ShareController {
#Autowired
private ShareBussines shareBussines;
#RequestMapping("/getShare/{ticker}")
public Share getShare(#PathVariable("ticker") String ticker) throws BrokerNotFoundException, BrokerArgumentException, BrokerGeneralException {
return shareBussines.getShare(ticker);
}
#RequestMapping(value="/buyShares", method=RequestMethod.POST)
public Map<Share, Integer> buyShares(#RequestBody Map<String,Double> sharesToBuy) throws BrokerGeneralException, BrokerArgumentException, BrokerInsufficientStockException {
return shareBussines.buyShares(sharesToBuy);
}
}
The problem is when I call the service from Postman.
The result is:
{
"Share [ticker=AMZN, name=Amazon, value=259.32126508258295]": 1,
"Share [ticker=GOOGL, name=Google, value=249.35339337497606]": 1,
"Share [ticker=FB, name=Facebook, value=181.15005639608364]": 55
}
The Map key is share.toString()... I want the key to be the share JSON.
I try to remove the toString method from Share class, but the result was:
{
"Share#1eb87f": 1,
"Share#40d9fab": 1,
"Share#8db": 54
}
It is using the Object's toString().
Thank you for your advice.
First, it works as you coded it to work:
#RequestMapping(value="/buyShares", method=RequestMethod.POST)
public Map<Share, Integer> buyShares(#RequestBody Map<String,Double> sharesToBuy) throws BrokerGeneralException, BrokerArgumentException, BrokerInsufficientStockException {
return shareBussines.buyShares(sharesToBuy);
}
Share is a key here. And that is kinda weird. Why not create some object like:
public class ShareResponse {
private Share share;
private Integer someVal; // that's the one you have in your Map as a value
// getters and setters
}
And afterward change your service a bit:
#RequestMapping(value="/buyShares", method=RequestMethod.POST)
public List<ShareResponse> buyShares(#RequestBody Map<String,Double> sharesToBuy) throws BrokerGeneralException, BrokerArgumentException, BrokerInsufficientStockException {
// do your business here, create a list of ShareResponse and return it
return shareBussines.buyShares(sharesToBuy); // instead of this
}
And you should get a valid, nicely 'formatted' JSON. If you need each item to be identifiable by some unique value just add some ID field to ShareResponse.
Does it make any sense?)
I've created CRUD methods but i have some problems with that.
This is my add method code:
public Product addProduct(Product content) {
Product item = new Product();
item.setName(content.getName());
item.setCalories(content.getCalories());
item.setFat(content.getFat());
item.setCarbo(content.getCarbo());
item.setProtein(content.getProtein());
item.setProductKinds(content.getProductKinds());
item.setAuthor(content.getAuthor());
item.setMedia(content.getMedia());
item.setApproved(content.getApproved());
databaseController.saveTest(item);
logger.log("Item created");
return item;
}
This is my editProduct method:
public Product editProduct(Product product) {
Product databaseProduct = databaseController.get(Product.class, product.getId());
databaseProduct.setAllProducts(product);
databaseController.save(databaseProduct);
return databaseProduct;
}
In model class I think that I have made everything right :
package pl.javamill.model.kitchen;
import com.amazonaws.services.dynamodbv2.datamodeling.*;
import pl.javamill.model.Request;
import pl.javamill.model.common.Author;
import pl.javamill.model.common.AuthorConverter;
import pl.javamill.model.common.Media;
import pl.javamill.model.common.MediaConverter;
import java.util.List;
#DynamoDBTable(tableName = "product")
public class Product extends Request {
/**
* Id of kitchen content
*/
private String id;
/**
* Name of product
*/
private String name;
/**
* Calories in 100g
*/
private Integer calories;
/**
* Fat in 100g
*/
private Double fat;
/**
* Total carbo in 100g
*/
private Double carbo;
/**
* Total Protein in 100g
*/
private Double protein;
/**
* Labels of product for example gluten fee product
*/
private List<ProductKind> productKinds;
/**
* Author of content.
*/
private Author author;
/**
* Address of content image.
*/
private Media media;
private Boolean approved;
#DynamoDBHashKey(attributeName = "id")
#DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBAttribute(attributeName = "Name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#DynamoDBAttribute(attributeName = "Calories")
public Integer getCalories() {
return calories;
}
public void setCalories(Integer calories) {
this.calories = calories;
}
#DynamoDBAttribute(attributeName = "Fat")
public Double getFat() {
return fat;
}
public void setFat(Double fat) {
this.fat = fat;
}
#DynamoDBAttribute(attributeName = "Carbo")
public Double getCarbo() {
return carbo;
}
public void setCarbo(Double carbo) {
this.carbo = carbo;
}
#DynamoDBAttribute(attributeName = "Protein")
public Double getProtein() {
return protein;
}
public void setProtein(Double protein) {
this.protein = protein;
}
#DynamoDBTypeConvertedEnum
#DynamoDBTypeConverted(converter = ProductKindConverter.class)
#DynamoDBAttribute(attributeName = "ProductKinds")
public List<ProductKind> getProductKinds() {
return productKinds;
}
public void setProductKinds(List<ProductKind> productKinds) {
this.productKinds = productKinds;
}
#DynamoDBTypeConverted(converter = AuthorConverter.class)
#DynamoDBAttribute(attributeName = "Author")
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
#DynamoDBTypeConverted(converter = MediaConverter.class)
#DynamoDBAttribute(attributeName = "Media")
public Media getMedia() {
return media;
}
public void setMedia(Media media) {
this.media = media;
}
#DynamoDBAttribute(attributeName = "Approved")
public Boolean getApproved() {
return approved;
}
public void setApproved(Boolean approved) {
this.approved = approved;
}
public void setAllProducts(Product product) {
if (!getName().equals(product.getName())) {
setName(product.getName());
}
if (!getCalories().equals(product.getCalories())) {
setCalories(product.getCalories());
}
if (!getFat().equals(product.getFat())) {
setFat(product.getFat());
}
if (!getCarbo().equals(product.getCarbo())) {
setCarbo(product.getCarbo());
}
if (!getProtein().equals(product.getProtein())) {
setProtein(product.getProtein());
}
if (!getProductKinds().equals(product.getProductKinds())) {
setProductKinds(product.getProductKinds());
}
if (!getAuthor().equals(product.getAuthor())) {
setAuthor(product.getAuthor());
}
if (!getMedia().equals(product.getMedia())) {
setMedia(product.getMedia());
}
if (!getApproved().equals(product.getApproved())) {
setApproved(product.getApproved());
}
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
if (name != null ? !name.equals(product.name) : product.name != null) return false;
if (calories != null ? !calories.equals(product.calories) : product.calories != null) return false;
if (fat != null ? !fat.equals(product.fat) : product.fat != null) return false;
if (carbo != null ? !carbo.equals(product.carbo) : product.carbo != null) return false;
if (protein != null ? !protein.equals(product.protein) : product.protein != null) return false;
if (productKinds != null ? !productKinds.equals(product.productKinds) : product.productKinds != null)
return false;
if (author != null ? !author.equals(product.author) : product.author != null) return false;
if (media != null ? !media.equals(product.media) : product.media != null) return false;
return approved != null ? approved.equals(product.approved) : product.approved == null;
}
#Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (calories != null ? calories.hashCode() : 0);
result = 31 * result + (fat != null ? fat.hashCode() : 0);
result = 31 * result + (carbo != null ? carbo.hashCode() : 0);
result = 31 * result + (protein != null ? protein.hashCode() : 0);
result = 31 * result + (productKinds != null ? productKinds.hashCode() : 0);
result = 31 * result + (author != null ? author.hashCode() : 0);
result = 31 * result + (media != null ? media.hashCode() : 0);
result = 31 * result + (approved != null ? approved.hashCode() : 0);
return result;
}
}
ProductKindConventor:
public class ProductKindConverter implements DynamoDBTypeConverter<String, List<ProductKind>> {
#Override
public String convert(List<ProductKind> objects) {
//Jackson object mapper
ObjectMapper objectMapper = new ObjectMapper();
try {
String objectsString = objectMapper.writeValueAsString(objects);
return objectsString;
} catch (JsonProcessingException e) {
//do something
}
return null;
}
#Override
public List<ProductKind> unconvert(String objectsString) {
ObjectMapper objectMapper = new ObjectMapper();
try {
List<ProductKind> objects = objectMapper.readValue(objectsString, new TypeReference<List<ProductKind>>(){});
return objects;
} catch (JsonParseException e) {
//do something
} catch (JsonMappingException e) {
//do something
} catch (IOException e) {
//do something
}
return null;
}
}
Save method in dbcontroller:
public void saveTest(Product product){
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(regions).build();
mapper = new DynamoDBMapper(client);
mapper.save(product);
}
Get product from DB method:
public Product getTest(String id) {
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(regions).build();
mapper = new DynamoDBMapper(client);
Product retrivedProduct = mapper.load(Product.class, id);
return retrivedProduct;
}
Unit test passed, everything seems to be ok, but when I was using POSTMAN to test, i got some errors. I send product as json and it seems like that:
{"id":null,"name":"yoloornotyolo","calories":1000,"fat":400.0,"carbo":20.0,"protein":40.0,"productKinds":["MEAT"],"author":{"name":"Plejer Annołn","id":"testID2"},"media":{"name":"heheszki","url":"http://blabla.pl","mediaType":"IMAGE"},"approved":false}
Then I got ""message": "Internal server error"", so I check log file and that what I can see:
not supported; requires #DynamoDBTyped or #DynamoDBTypeConverted:
com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException
I dont know what is wrong. Can someone explain me what I suppose to do?
It would be useful to see your saveProduct method. You are using DynamoDBMapper annotations but it looks like you are trying to save an item object, not a Product object. Rather than
Item item = new Item()
Use
Product item = new Product();
item.setName...
One thing I would mention is that you can offload the handling of your generated id to DyanmoDBMapper using the DynamoDBAutoGeneratedKey annotation
In your model class do this:
#DynamoDBHashKey(attributeName = "Id")
#DynamoDBAutoGeneratedKey
public String getId() { return id; }
public void setId(String id) { this.id = id; }
And then you dont need to handle id in your addProduct method
EDIT: Your saveProduct method should be along the lines of
DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
mapper.save(item)
I doubt you need to be passing a tablename as that is an annotation on your Product object. You shouldn't be using putItem.
EDIT:
Your saveProduct method should take a Product object, not an item object. Dont use putItem because this doesn't know about your model class. Use DynamoDBMapper save function. You dont need to specify the table name as that's an annotation on your Product class (the table is called 'product'). You should use AmazonDynamoDB for interfacing to DynamoDB. The method below return is void, so you will need to update the addProduct method.
public void saveProduct(Product item) {
logger.log("Starting to save an item");
//You need a new method to return an AmazonDynamoDB interface
AmazonDynamoDB dynamoDB = getAmazonDynamoDB();
DynamoDBMapper mapper = new DynamoDBMapper(dynamoDB);
mapper.save(item)
logger.log("Item stored");
return saved;
}
EDIT:
You build an AmazonDynamoDB interface like this
// Set to your chosen region
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(Regions.US_WEST_2)
.build();
EDIT:
DynamoDBMapper only supports certain data types.
You have three complex data types there; productKind, author and media. If you want to store these in your database, you will need to write a Convertor Class for each one. The convertor class typically define how you convert your object to a string and back again.
EDIT: Your set, ProductKind, will need a convertor that looks like this. Just change 'MyObject' to ProductKinds.
It would be useful to have a stack trace for the exception. In the intermediate message it contains the data type and field information which can not be converted.
Usually you do not need to make any convertors, just be sure to have #DynamoDBDocument on all custom classes, and #DynamoDBTypeConvertedEnum on all custom enums used.
I also had this error and it is a bit misleading, all we need to do is use #DynamoDBDocument on the class file of the referenced classes.
For your case, just put this annotation on ProductKind, like this:
#DynamoDBDocument
class ProductKind {
...
}
It should persist into dynamoDB as a map in the product table.
you will run into this error if the mapper class is
missing a No-Arg constructor
or has
invalid Setters/Getters
that do not comply with the camel case convention.
(Solved) Error: could not unconvert attribute dynamodb
I have a TableView and a form with some TextBox and ComboBox in my javafx application. I am trying to populate the form components with selected rows data from TableView. I can populate all the TextBox without any error or exception. But while setting values to ComboBoxes, it's throwing an ClassCastException, java.lang.ClassCastException: java.lang.String cannot be cast to entity.StockUOM.
This is my StringCoverter
unitCombo.setConverter(new StringConverter<StockUOM>() {
#Override
public String toString(StockUOM object) {
return object.getStockUOM();
}
#Override
public StockUOM fromString(String string) {
return null;
}
});
This is my entity.StockUOM class
#Entity
#Access(AccessType.PROPERTY)
#NamedQueries({
#NamedQuery(name = StockUOM.findStockUOM, query = "SELECT s from StockUOM s")
})
public class StockUOM implements Externalizable{
public final static String PREFIX = "entity.StockUOM.";
public final static String findStockUOM = PREFIX + "findStockUOM";
private IntegerProperty id;
private int _id;
private StringProperty stockUOM;
private String _stockUOM;
public StockUOM() {
if (id == null) {
id = new SimpleIntegerProperty(this, "id", _id);
}
if( stockUOM== null){
stockUOM= new SimpleStringProperty(this,"stockUOM",_stockUOM);
}
}
public StockUOM(String stockUOM) {
this();
this.stockUOM.set(stockUOM);
}
public IntegerProperty idProperty() {
if (id == null) {
id = new SimpleIntegerProperty(this, "id", _id);;
}
return id;
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public final int getId() {
if (id == null) {
return _id;
} else {
return id.get();
}
}
public final void setId(int id) {
if (this.id == null) {
_id = id;
} else {
this.id.set(id);
}
}
public StringProperty stockUOMProperty() {
if( stockUOM== null){
stockUOM= new SimpleStringProperty(this,"stockUOM",_stockUOM);
}
return stockUOM;
}
public final String getStockUOM() {
if(stockUOM == null){
return _stockUOM;
}else{
return stockUOM.get();
}
}
public void setStockUOM(String stockUOM) {
if (this.stockUOM == null) {
_stockUOM=stockUOM ;
} else {
this.stockUOM.set(stockUOM);
}
}
#Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(getId());
out.writeChars(getStockUOM());
}
#Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
setId(in.readInt());
setStockUOM((String)in.readObject());
}
#Override
public String toString() {
return getStockUOM();
}
}
This is how i am setting values to ComboBox
unitCombo.setValue(newValue.getUnit());
Here newValue is the instance of StockUOM of ChangeListner which is listening on TableView row selection.
So what's wrong i am doing ? And what's the solution.
Thanks.
The problem is that most probably you defined your ComboBox like:
ComboBox unitCombo = new ComboBox();
So you missed to define the generic argument and you ended up with the raw type (your IDE most probably gives you a warning on this line).
At this point it is not specified what kind of objects do you want to display in the ComboBox.
When you do the following:
unitCombo.setValue(newValue.getUnit());
you set the valueProperty as a String value.
And then comes your converter:
unitCombo.setConverter(new StringConverter<StockUOM>() {
#Override
public String toString(StockUOM object) {
return object.getStockUOM();
}
#Override
public StockUOM fromString(String string) {
return null;
}
});
which expects StockUOM object being displayed, which does not happen hence the error.
You have to decide what kind of object do you want to display: if it is StockUOM, then declare the ComboBox as ComboBox<StockUOM> unitCombo = new ComboBox<StockUOM>();. After this you will have a compile time error on the line where you set the value for a String value, to fix that error you have to modify that line as unitCombo.setValue(newValue);. If you want to display String objects, the methodology is the same.
I use GWTP-Rest and i need to deserialize an dto which contains an ListMultimap. All the elements of the dto are deserialize but not the ListMultimap. below the code of dto. JsonAnnotation are working and come from the correct artifactId which is compatible with gwt-jackson. I imports with maven gwt-guava-jackson and inherits the module.
public class GetdtoMobileResult implements ExpirableResult, DtoData {
#JsonProperty("diffusions")
private ListMultimap<Integer, Diffusion> diffusions;
private TimeInterval visibleRange;
#JsonProperty("ttl")
private long ttl;
private dtoHourRange hourRange;
GetTVGuideMobileResult() {
super();
}
public GetTVGuideMobileResult(
final ArrayListMultimap<Integer, Diffusion> diffusions,
final TimeInterval visibleRange, final long ttl, final MediamatHourRange range) {
super();
this.diffusions = diffusions;
this.visibleRange = visibleRange;
this.ttl = ttl;
this.hourRange = range;
}
#JsonIgnore
#Override
public ListMultimap<ChannelId, Diffusion> getDiffusions() {
return ArrayListMultimap.create();
}
#JsonProperty("diffusions")
public ListMultimap<Integer, Diffusion> getdiffusions()
{
return diffusions;
}
#Override
public TimeInterval getVisibleRange() {
return visibleRange;
}
#JsonProperty("ttl")
#Override
public long ttl() {
return ttl;
}
#Override
public dtoHourRange getHourRange() {
return hourRange;
}
// #### setter add to able deserialization on client side mobile. ######
#JsonProperty("diffusions")
public void setDiffusions(final ListMultimap<Integer, Diffusion> diffusions) {
this.diffusions = diffusions;
}
public void setHourRange(final dtoHourRange hourRange) {
this.hourRange = hourRange;
}
#JsonProperty("ttl")
public void setTtl(final long ttl) {
this.ttl = ttl;
}
public void setVisibleRange(final TimeInterval visibleRange) {
this.visibleRange = visibleRange;
}
}
I receive the correct object from server {"diffusions":{"..."} ,...}. Serialization is doing by the lib jackson-datatype-guava, which if i correctly understood is using by jackson-guava. Interface which are implements define getter of the object, and implements Serializable.
I have another problem's, probably linked to his, my ListMultimap use normaly an dto as key which wrap an integer, but jackson tell me that my dto is not supported as map's key. Code of my dto :
public class DtoId implements Serializable {
/**
* serial version Uid
*/
private static final long serialVersionUID = -5816632906385308130L;
private int id;
DtoId() {
// for serialization
}
public DtoId(final int id) {
super();
this.id = id;
}
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
#Override
public String toString() {
return Integer.toString(id);
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ChannelId other = (ChannelId) obj;
if (id != other.id) {
return false;
}
return true;
}
}
Ok, problem's come from bad dependency between project on guava. I provided same version of guava to the client, shared & server, now serialization works, sorry to the bad question.
Second error continue to occurs, i will post this on an other page.
I have a DropDownChoice :
DropDownChoice timePeriod = new DropDownChoice("timePeriod", Arrays.asList(new TimePeriod(1, "Weekly"), new TimePeriod(2, "Bi-Weekly"), new TimePeriod(3, "Semi-Monthly"), new TimePeriod(4, "Monthly"), new TimePeriod(5, "Yearly")), new IChoiceRenderer() {
private static final long serialVersionUID = 10102L;
#Override
public String getIdValue(Object object, int index) {
return ((TimePeriod) object).getId() + "";
}
#Override
public Object getDisplayValue(Object object) {
return ((TimePeriod) object).getPeriodType();
}
});
timePeriod.setNullValid(false);
My question is:
How to set the selected index to 2 or any other?
How to remove first default blank option?
Thank you.
You should be able to set the selected index by using a PropertyModel instead of hard-coding the values of the dropdown. I can't test at the moment, but it would be something like
String timePeriodValue = "Bi-Weekly";
DropDownChoice timePeriod = new DropDownChoice("timePeriod",
new PropertyModel(this, "timePeriodValue"),
Arrays.asList(/* your options */),
new IChoiceRenderer() {
// ...
// Again, this is pseudocode only
As a bonus, the very act of setting a default value should eliminate the blank option problem.
DropDownChoice has a constructor which accepts the default value.
Or in your code you can add timePeriod.setModel(Model.of(new TimePeriod(2, "Bi-Weekly")))
I guess TimePeriod has proper #equals() and #hashCode() implementations.
About the blank option: see org.apache.wicket.markup.html.form.AbstractSingleSelectChoice.isNullValid()
Lord Torgamus and martin-g thank you both of you. I did a small test. And it is working perfectly. As Lord Torgamus indicated,
#SuppressWarnings({ "unchecked", "rawtypes", "serial" })
public class MyPage extends WebPage {
public MyPage() {
add(new MyForm("form"));
}
private class MyForm extends Form {
public MyForm(String id) {
super(id);
setOutputMarkupPlaceholderTag(true);
setModel(new Model(new FormModel()));
final DropDownChoice timePeriod = new DropDownChoice("timePeriod", new PropertyModel(getModel(), "timePeriod"), Arrays.asList(new TimePeriod(1, "Weekly"), new TimePeriod(2, "Bi-Weekly"), new TimePeriod(3, "Semi-Monthly"), new TimePeriod(4, "Monthly"), new TimePeriod(5, "Yearly")), new IChoiceRenderer() {
private static final long serialVersionUID = 10102L;
#Override
public String getIdValue(Object object, int index) {
return ((TimePeriod) object).getId() + "";
}
#Override
public Object getDisplayValue(Object object) {
return ((TimePeriod) object).getPeriodType();
}
});
timePeriod.setNullValid(false);
add(timePeriod);
timePeriod.setOutputMarkupPlaceholderTag(true);
timePeriod.add(new AjaxFormComponentUpdatingBehavior("onChange") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
MyForm form = (MyForm) timePeriod.getParent();
FormModel formModel = (FormModel) form.getModelObject();
formModel.setTimePeriod(new TimePeriod(4, "Monthly"));
form.setModel(new Model(formModel));
target.addComponent(form);
}
});
}
#Override
public void onSubmit() {
System.out.println(getModelObject());
}
}
private class FormModel implements Serializable {
private TimePeriod timePeriod = new TimePeriod(2, "Bi-Weekly");
public FormModel() {
}
public TimePeriod getTimePeriod() {
return timePeriod;
}
public void setTimePeriod(TimePeriod timePeriod) {
this.timePeriod = timePeriod;
}
#Override
public String toString() {
return "FormModel [timePeriod=" + timePeriod + "]";
}
}
private class TimePeriod implements Serializable {
private int id;
private String periodType;
public TimePeriod(int id, String periodType) {
super();
this.id = id;
this.periodType = periodType;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPeriodType() {
return periodType;
}
public void setPeriodType(String periodType) {
this.periodType = periodType;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + id;
result = prime * result + ((periodType == null) ? 0 : periodType.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TimePeriod other = (TimePeriod) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (id != other.id)
return false;
if (periodType == null) {
if (other.periodType != null)
return false;
} else if (!periodType.equals(other.periodType))
return false;
return true;
}
private LoginPage getOuterType() {
return LoginPage.this;
}
#Override
public String toString() {
return "TimePeriod [id=" + id + ", periodType=" + periodType + "]";
}
}
}
The above code is provided for other users as it might be helpful and I wrote it for testing purpose so all the classes are written in one .java file although it is not advisable.
Thank you.