A Solution to Hierarcy Cycle Problem with JSON: JSON Filter

6 06 2008

When you have a cycle in your domain model, beacuse sometimes you realy need it*, then with Spring JsonView, indeed you may have same problem in different cases, while converting Java objects to JSON objects, you can get en error :

net.sf.json.JSONException: There is a cycle in the hierarchy!

with a following unusefull stack trace:)

First of all, think carefully fi you really do need this cycle in the dependency. If you don’t, remove it.
If you do, the you can use, JSON filters.

I will give an example code to show it. In the code, resulting JSON object will contain only id, name and description fields and values of the objects.

     JsonConfig config = new JsonConfig();
     config.setJsonPropertyFilter(new PropertyFilter() {
        public boolean apply(Object source, String name, Object value) {
              if ("name".equals(name) || "description".equals(name) || "id".equals(name)) {
                  return false;
              }
              return true;
           }
       });
       List jsonObjects = new ArrayList();
       for (Object object : objects) {
           jsonObjects.add(JSONSerializer.toJSON(object, config));
       }
     //Here you have jsonObjects, do whatever you need.
      ...

This is a sample code. It depends on you how to use this in a proper way! :)

* Consider, you have an class X with composition Y, and in Y class, if you need all Xs referenced by Y, then you will probably have a property containing list of X. Then you have cycle! For example, Employee works on a Department, so Employee has a composition with Department, in Department you need all employees workin in this department.





Ext JS Tip : How To Make ComboBox Send Value Field.

19 05 2008

When you use Ext JS’s ComboBox, if you don’t set hidden name or id, it send display field value, not value field. To handle this, it has to be set. Be careful about uniqueness of the hidden name, for more details you can check Ext JS ComboBox’s documantation

var unitField = new Ext.form.ComboBox({   
    id:'unitField',   
    name: 'unit',   
    fieldLabel: 'Unit',   
    store:unitStore,   
    mode: 'remote',   
    displayField: 'name',   
    valueField: 'id',   
    hiddenName : 'unitId',   
    allowBlank: false,   
    anchor:'95%',   
    triggerAction: 'all'
});




How to Populate Ext JS ComboBox using Spring Controller

15 05 2008

To populate Ext JA ComboBox using Spring Controller, you can create an Ajax request using Ext.data.HttpProxy and as response you can return Json Objects. And using JsonReader, you can read values and pupolate ComboBox.

Requirements
* Spring
* ExtJS 2.0
* json-lib
* spring-json

Here is class of the combobox’s item :

public class Unit { private long id private String name;

 public Unit(long id, String name){
     this.id = id;   this.name = name;
 }

 public String getName() {
     return name;
 }

 private void setName(String name) {
    this.name = name;
 }

 public long getId() {
   return id;
 }

 private void setId(long id) {
    this.id = id;
 }
}

Here is the controller. It is multiaction controller. But it does not have to be so. The request is mapped to loadUnits() method, which retrieves units from a source (here it is a method, it can be a repository), and returns a JSonView as a view.

import java.util.ArrayList;import java.util.List;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.JsonView;

@Controller
public class MyMultiController {

 @RequestMapping("/getunits.do")
 public ModelAndView loadUnits() {
    //Somehow get units.
    List units = getUnits();
    return new ModelAndView(new JsonView(), "units", units);
 }

 private List getUnits() {
    List units =  new ArrayList();
    units.add(new Unit(1, "Unit 1"));
    units.add(new Unit(2, "Unit 2"));
    return units;
 }
}

Here is the ExtJs Code for ComboBox. It creates Ext.data.HttpProxy, which is an implementation of Ext.data.DataProxy that reads a data object from an Ext.data.Connection object configured to reference a certain URL. It gets data from getsunits.do url. And mode od the unit combobox is set to remote.

var unitStore = new Ext.data.Store({
    proxy: new Ext.data.HttpProxy({
        url: 'getunits.do'
    }),
    reader: new Ext.data.JsonReader({
           root:'units'
         },
         [{name: 'id', mapping:'id'}, {name: 'name' , mapping:'name'}])
});

 var unitField = new Ext.form.ComboBox({
      id:'unitField',
      name: 'unit',
      fieldLabel: 'Unit',
      store:unitStore,
      mode: 'remote',
      displayField: 'name',
      allowBlank: false,
      valueField: 'id',
      hiddenName : 'unitId',
      anchor:'95%',
      triggerAction: 'all'
 });

When you put the unitField in a form, then it will be populated when the user clicks the combobox.
I hope it is helpful.








Follow

Get every new post delivered to your Inbox.