JsonlibJsonStringWriter - JSON-lib support

  1. Instruction
  2. Simple Binding
  3. Binding to CommandBean-Property
  4. Convert all Model Values
    1. Convert all values of Model-Map by CustomEditor
    2. Convert specific value in Model-Map by CustomEditor
  5. Register JsonlibJsonWriterConfiguratorTemplates
  6. Other configuration
    1. Keep null - values in the json output

Instruction

NEWS :
Thanks to francesco -- original ideas we are able to localise properties of the ComandBean by the CommensBeanUtils-Syntax.

So the binding capabilities are now the same like the SojoJsonStringWriter or XStreamJsonStringWriter

  1. You can bind a CustomEditor to Global value class types like java.util.Date

  2. You can bind a CustomEditor to Properties of the ComandBean located by the CommensBeanUtils-Syntax

  3. Optional: To any other object in the model like those added in the referenceData-method.

  4. The JsonlibJsonStringWriter supports implizite and explicite collection property binding

    • implizite: bean.list.property: locates all properties of the collection from index 0-n

      and

    • explicite: bean.list[1].property: locates properties implicate Collection-Beans with EXPIZITE index
  5. JsonlibJsonWriterConfiguratorTemplate enables you to use some of the Advanced Features of JSON-lib. For example you can use filtering or build events.

  6. Compared to the SojoJsonStringWriter or the XStreamJsonStringWriter all unconverted values do allway keep there orginal type

  7. Since spring-json-1.3.0 the null values are excluded from the json output. You can get the old behaviour by setting the "keepNullProperties" - property in the spring-configuration
Attention :
The JsonlibJsonWriter registers a own JsonValueProcessor and matches it with JsonValueProcessorMatcher.
  • The JsonValueProcessor enables the JsonlibJsonWriter to use the CustomEditors registered in the initBinder method.
  • The JsonValueProcessorMatcher matches all values to the JsonValueProcessor. The JsonValueProcessor decides whether the value going to be converted or not.

If you are considering registering a custom JsonValueProcessor or BeanProcessor, bear in mind that you may change the behaviour of the JsonlibJsonWriter in a way you don't expect!. Test your application well.

  • Any custom behaviour you register does not interfere with the "request-attribute to CommandBean" binding and converting.

Using

Register a JsonlibJsonStringWriter-Bean to the JsonView.

<beans>
    <bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
            <property name="jsonWriter"><ref bean="jsonlibJsonWriter"/></property>
    </bean>
        
        <bean name="jsonlibJsonWriter" class="org.springframework.web.servlet.view.json.writer.jsonlib.JsonlibJsonStringWriter"/>
</beans>

Simple Binding

initBinder Source:
=================

@Override
protected void initBinder(HttpServletRequest request,  
                        ServletRequestDataBinder binder) throws Exception{
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
        CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
        binder.registerCustomEditor(Date.class, editor);
}

Result:
=======

{"command":{
            "birthday":"30-01-2008", 
            "marriage":"30-01-2008", 
            "placeofbirth":"Sydney",
            "age":40,
            "childs": true
}}

Binding to CommandBean-Property

Properties of the CommandBean are located by the CommonsBeanUtils-Syntax

initBinder Source: 
==================
@Override
protected void initBinder(HttpServletRequest request,  
                ServletRequestDataBinder binder) throws Exception{
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
        CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
        binder.registerCustomEditor(Date.class, "birthday", editor);
}

Result:
======

{"command":{
          "birthday":"30-01-2008",
          "marriage":"Wed Jan 30 00:00:00 GMT 2008",
          "placeofbirth":"Sydney",
          "age":40,
          "childs": true
}}

Convert all Model Values

The SojoJsonStringWriter does provide the optional conversion of non CommandBean-Values of the model map. You have to activate this feature by setting the convertAllMapValues property in the JsonWriter-Bean in the view.xml.

You can locate them by registering a CustomEditor for a field starting with (non_commandbean_key).

  • (name_in_model_map_key).property
  • (key).list[1].property
<beans>
    <bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
        <property name="jsonWriter"><ref bean="jsonWriter"/></property>
    </bean>
    
    <bean name="jsonWriter" 
          class="org.springframework.web.servlet.view.json.writer..jsonlib.JsonlibJsonStringWriter">
        <property name="convertAllMapValues"><value>true</value></property>
    </bean>
</beans>

Convert all values in Model-Map by CustomEditor

initBinder Source:
==================
@Override
protected void initBinder(HttpServletRequest request,  
                ServletRequestDataBinder binder) throws Exception{
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
        CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
        binder.registerCustomEditor(Date.class, editor);
}
        
Result:
=======

{"signdate":"30-01-2008",
 "command":{
            "birthday":"30-01-2008",
            "marriage":"30-01-2008",
            "placeofbirth":"Sydney",
             "age":40,
            "childs": true
}}

Convert specific values in Model-Map by CustomEditor

initBinder Source:
==================
@Override
protected void initBinder(HttpServletRequest request,  
                ServletRequestDataBinder binder) throws Exception{
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
        CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
        binder.registerCustomEditor(Date.class, "birthday", editor);
        binder.registerCustomEditor(Date.class, "(signdate)", editor);
}
        
Result:
=======

{"signdate":"30-01-2008",
 "command":{
            "birthday":"30-01-2008",
            "marriage":"Wed Jan 30 00:00:00 GMT 2008",
            "placeofbirth":Sydney,
            "age":40,
            "childs": true
}}

Register JsonlibJsonWriterConfiguratorTemplates

If you want to use a JsonlibJsonWriterConfiguratorTemplate, you have to

  1. set the "enableJsonConfigSupport"-property of the JsonlibJsonStringWriter.
  2. implement the abstract "JsonlibJsonWriterConfiguratorTemplate".
  3. register the JsonlibJsonWriterConfiguratorTemplate at the JsonWriterConfiguratorTemplateRegistry.

It is recommended to register the JsonlibJsonWriterConfiguratorTemplate in the initBinder method but you can register it in any controller method you can reach the request. This even could be the handleRequest method of an ControllerInterface implementation.

Set the "enableJsonConfigSupport"-property in the spring-configuration

<beans>
    <bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
            <property name="jsonWriter"><ref bean="jsonlibJsonWriter"/></property>
    </bean>
        
        <bean name="jsonlibJsonWriter" class="org.springframework.web.servlet.view.json.writer.jsonlib.JsonlibJsonStringWriter">
        <property name="enableJsonConfigSupport"><value>true</value></property>
    </bean>
</beans>

Register the JsonlibJsonWriterConfiguratorTemplate

initBinder Source:
==================
@Override
protected void initBinder(HttpServletRequest request,  ServletRequestDataBinder binder) throws Exception{
                
    JsonWriterConfiguratorTemplateRegistry registry = JsonWriterConfiguratorTemplateRegistry.load(request);             
    registry.registerConfiguratorTemplate(
         new JsonlibJsonWriterConfiguratorTemplate(){
                @Override
                public JsonConfig getJsonConfig() {
                    JsonConfig config =  new JsonConfig();
                                                
                    // Exclude all date properties 
                    config.setJsonPropertyFilter( new PropertyFilter(){  
                    public boolean apply( Object source, String name, Object value ) {  
                          if( value != null && Date.class.isAssignableFrom( value.getClass() ) ){  
                              return true;  
                          }  
                          return false;  
                       }  
                    });  
                    return config;
                }
         }
   );
}
        
Result:
=======

{
 "command":{
            "placeofbirth":"Sydney"
}}

Other configuration

Keep null - values in the json output

In some cases you can keep the null values from the model. This was the default behaviour until spring-json-1.2.1. Since spring-json-1.3.0 the null values are excluded from the json output. You can get the old behaviour by setting the "keepNullProperties" - property in the spring-configuration

<beans>
    <bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
            <property name="jsonWriter"><ref bean="jsonlibJsonWriter"/></property>
    </bean>
        
        <bean name="jsonlibJsonWriter" class="org.springframework.web.servlet.view.json.writer.jsonlib.JsonlibJsonStringWriter">
        <property name="keepNullProperties"><value>true</value></property>
    </bean>
</beans>

By setting the keepNullProperties property a JsonPropertyFilter is added.

 jsonConfig.setJsonPropertyFilter( new NullPropertyFilter()); 

Keep in mind that registering a JsonPropertyFilter in a JsonlibJsonWriterConfiguratorTemplate overwrites this behaviour. Implement the null filtering feature in your custom JsonPropertyFilter like:

public class NullPropertyFilter implements PropertyFilter {

        public boolean apply( Object source, String name, Object value ) {  
        if( value == null  ){  
           return true;  
        }  
        
        // do your stuff
        
        return false;  
    }

}