スプリングにjson形式の入出力を配置します.

11664 ワード

今のプロジェクトでは、携帯端末、ウェブサイトajaxの非同期要求など、Jsonの入出力を使うことが多いです.以下は私自身がjavaプロジェクトの中で比較的に良いjsonを使って輸出する方式に出会うのです.
 
一、springに入出力jsonのサポートを配置します.
    1.jacksonのカバンを導入する
          jackson-core-asl-1.9.13.jar
          jackson-mapper-asl-1.9.13.jar
          jackson-core-lgpl-1.9.13.jar
          jackson-mapper-lgpl-1.9.13.jar
      ここでmavenの配置を提供します.
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-core-asl</artifactId>
			<version>1.9.13</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.13</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-core-lgpl</artifactId>
			<version>1.9.13</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-lgpl</artifactId>
			<version>1.9.13</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
 
 
     2.springプロファイルに追加する
	<bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
    	<property name="messageConverters">
 		<list>
   			<ref bean="mappingJacksonHttpMessageConverter" /><!-- json    -->
  		</list>
		</property>
	</bean>
	<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
	</bean>
 
     3.入出力するcontrollerを使う方法に@Request Bodyを加える 和 @ResonseBody
//JsonRequest JsonResponse            
public @ResponseBody JsonResponse process(@RequestBody JsonRequest request) {
	return new JsonResponse();
}
 
   Json Resonse.java
public class Response implements Serializable {
    private static final long serialVersionUID = 7015731184314121850L;
    private String cmd;
    private String token;
    public String getCmd() {
        return cmd;
    }

    public void setCmd(String cmd) {
        this.cmd = cmd;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }
}
 
 
   Json Request.java
public class JsonRequest {
    String cmd;
    String cmdtype;
    
    public String getCmd() {
        return cmd;
    }

    public void setCmd(String cmd) {
        this.cmd = cmd;
    }

    public String getCmdtype() {
        return cmdtype;
    }

    public  void setCmdtype(String cmdtype) {
        this.cmdtype = cmdtype;
    }

}
 
 
    これで簡単なjavaBeanは自動的にjson文字列の配置になります.
    テストの例
    header
{"Content-Type":"application/json"}
 
 
    Jsonお願いします   
{
	"cmd":"get msg", 
	"cmdtype":""
}
 
 
    Jsonは帰ります 
{
	"cmd": "get msg",
	"token": ""
}
 
 
    
 
二、jacksonの多状態を利用して、springは自動的にサブクラスを識別します.
     また、JsonRequestにDataカスタムクラス変数が含まれているような複雑なエンティティもたくさんあります.どうやって変換しますか?
      Json Request.java 
public class Request {
    String cmd;
    String cmdtype;
    Data data; // data     :            ,Collection、Map    ,JavaBean
    public String getCmd() {
        return cmd;
    }

    public void setCmd(String cmd) {
        this.cmd = cmd;
    }

    public String getCmdtype() {
        return cmdtype;
    }

    public  void setCmdtype(String cmdtype) {
        this.cmdtype = cmdtype;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }
}
 
    1.jacksonの多さ   
Jackson           java      json          。                  ,Jackson               ,                      。
 
    方式1
objectMapper.enableDefaultTyping(); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    
DefaultTyping      
JAVA_LANG_OBJECT:          Object   
OBJECT_AND_NON_CONCRETE:          Object       (      )   
NON_CONCRETE_AND+_ARRAYS:    ,                          
NON_FINAL:      final     final       
  DefaultTyping,       final                               。
 
 
    方式二
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
class Animal { }
 
use=JsonTypeInfo.Id.CLASS:                 
include=JsonTypeInfo.As.PROPERTY:                  
property="@class"           @class
use      
CLASS      
MINIMAL_CLASS   ,           ,     
NAME    ,               
CUSTOM  @JsonTypeIdResolver  
include     
PROPERTY              
WRAPPER_OBJECT      ,         
WRAPPER_ARRAY         ID,           
 
    参照リンク:http://codelife.me/blog/2012/11/03/jackson-polymorphic-deserialization/
 
 
    2.クラスに@JsonType Infoを追加します.
     私が見たのは使い方二@JsonType Info(use=Json Type Info.Id.Class、include=JsonType Info.As.PROPARTY、property=「@class」)です.
 
    DataインターフェースData.java     
//      :   Json   Data    ?  Json    "dt"     ,            。
@JsonTypeInfo(include = As.PROPERTY, property = "dt", use = Id.NAME)
public interface Data extends Serializable {
}
 
 
    data_という名前ですimplのDataインターフェースの中の一つの実現クラスDataImpl.java 
@JsonTypeName("data_impl")
public class DataImpl implements Data{
	private static final long serialVersionUID = 6904642231937403932L;
	private String name;
	private Integer value;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getValue() {
		return value;
	}
	public void setValue(Integer value) {
		this.value = value;
	}
}
 
 
 
    3.SpringでBenPostProcessorインターフェースの紹介
public interface BeanPostProcessor {

	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}
     BeanPostProcessorはspringがBeanエンティティに対して前処理するインターフェースであり、BeanPostProcessorインターフェースのクラスがspringに注入されて管理されると、自動的に負荷エンティティの前後でその方法を呼び出すことができます.
     Spring 3.0とSpring 3.1のバージョンは違っていますので、Jacksonを結合した処理は少し違っています.そうでないと、サブクラスのjsonがあります.具体的なコードは以下の通りです.
     
@Component
public class JsonObjectMapperConfiguration implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @SuppressWarnings("deprecation")
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    	//spring 3.1  
        if (bean instanceof RequestMappingHandlerAdapter) {
        	RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean;
        	List<HttpMessageConverter<?>> converters = adapter.getMessageConverters();
            for (HttpMessageConverter<?> converter : converters) {
                if (converter instanceof MappingJacksonHttpMessageConverter) {
                    MappingJacksonHttpMessageConverter jsonConverter = (MappingJacksonHttpMessageConverter) converter;
                    ObjectMapper mapper = new ObjectMapper();
                    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, true);
                    SerializationConfig config = mapper.getSerializationConfig();
                    config.setSerializationInclusion(Inclusion.NON_NULL);
                    mapper.registerSubtypes(DataImpl.class);
                    jsonConverter.setObjectMapper(mapper);
                }
            }
        }
    	
        /* sping3.0
        if (bean instanceof AnnotationMethodHandlerAdapter) {
            AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) bean;
            HttpMessageConverter<?>[] converters = adapter.getMessageConverters();
            for (HttpMessageConverter<?> converter : converters) {
                if (converter instanceof MappingJacksonHttpMessageConverter) {
                    MappingJacksonHttpMessageConverter jsonConverter = (MappingJacksonHttpMessageConverter) converter;
                    ObjectMapper mapper = new ObjectMapper();
                    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, true);
                    SerializationConfig config = mapper.getSerializationConfig();
                    config.setSerializationInclusion(Inclusion.NON_NULL);
                    mapper.registerSubtypes(DataImpl.class);
                    jsonConverter.setObjectMapper(mapper);
                }
            }
        }
        */
        return bean;
    }
}
 
 
    要求されたjsonにDataを持つクラスのメンバー変数パラメータを加えることができます.
    ダタへの加入を要請した後
{
  "cmd": "get msg",
  "cmdtype": "",
  "data": {
    "dt": "data_impl",
    "name": "ok",
    "value": 2
  }
}
    帰ってもdataに参加できます.
{
	"cmd": "12323",
	"token": "ok=2",
	"data": {
		"dt": "data_result",
		"name": "okasdf"
	}
}
 
 
三、まとめ
     以上は、所望の効果を達成するために、dtを使用してインターフェースデータの種類を定義し、cmdでapiの名前を定義することができます.