struts2中的JSON插件中的一个小猫腻

来源:互联网 发布:传奇屠龙 知乎 编辑:程序博客网 时间:2024/05/14 17:17

在struts2中,对对象进行序列化的过程,往往会有一些控制行为的参数,例如包含什么样的属,不包含什么样的属,根对象等,其中有一个对象值得一提,就是ignoreHierarchy,这个属性设计的初忠是控制在序列化对象的过程中,是否对此对象所继承的属性也进行序列化,例如下面的一段代码:

public abstract class CrudBaseActionSupport<B extends BaseModel<?>> extendsActionSupport implements IDataWrapperProvider<B>, IResultPostProcessor,CoreConstants {public OperatorFunction getOperatorFunction() {return this.crudBaseService.getOperatorFunction(this.getDataWrapper());}public CrudBaseService<B> getCrudBaseService() {return crudBaseService;}public void setCrudBaseService(CrudBaseService<B> crudBaseService) {this.crudBaseService = crudBaseService;}}

另外有一个类如果继承了这个类,那么此类中的属性operatorFunction与crudBaseService这两个属性就会受到ignoreHierarchy配置项的影响,如果ignoreHierarchy=true则在序列化子类对象的时候这两个属性就不会进行序列化,而如果ignoreHierarchy=false则会对这两个属性进行序列化,但这是种控制仅仅限于它的子类对象作为根情况下才适用这一规则,什么意思呢?比如这个类的子类对象它是作为一个列表中的一成员而存在,则这个子类对象两个超类属即使用在ignoreHierarchy=true情况下它仍然会被序列化,关于这一点你一定有小心,不要想当然,认为只要将此属性设置true,就在任何情况下它都不会被序列化.

如果你想在任何情况下都不序列化可以通过两种手段实现:1.使用JSON标注来完成;2.通过excludeProperties属性配置,当然如果你还想达到非常灵活的控制你还可以使用插件提供的桥接标注与接口来完成比较灵活的定制,主要用涉及到的类如下:

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface JSONFieldBridge {    Class<? extends FieldBridge> impl() default StringBridge.class;    public JSONParameter[] params() default {};}

@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)public @interface JSONParameter {    String name();

    String value();}

public interface FieldBridge {    String objectToString(Object object);}
public class StringBridge implements FieldBridge{    public String objectToString(Object object) {        if(object==null) return null;        return object.toString();    }}

public interface ParameterizedBridge {

    void setParameterValues(Map<String,String> parameters);}

 

//这是在桥扩展中最重要的一段代码逻辑,它主用来处理当一个方法被打上桥接标注之后该如何处理序列化的逻辑,对应前台几个接口与标不难看出下面这个方法所完成的事情

private Object getBridgedValue(Method baseAccessor, Object value) throws InstantiationException, IllegalAccessException {        JSONFieldBridge fieldBridgeAnn = baseAccessor.getAnnotation(JSONFieldBridge.class);        if (fieldBridgeAnn != null) {            Class impl = fieldBridgeAnn.impl();            FieldBridge instance = (FieldBridge) impl.newInstance();            if (fieldBridgeAnn.params().length > 0 && ParameterizedBridge.class.isAssignableFrom(impl)) {                Map<String, String> params = new HashMap<String, String>(fieldBridgeAnn.params().length);                for (JSONParameter param : fieldBridgeAnn.params()) {                    params.put(param.name(), param.value());                }                ((ParameterizedBridge) instance).setParameterValues(params);            }            value = instance.objectToString(value);        }        return value;    }

	
				
		
原创粉丝点击