我在使用REST Web服务中的Jackson解析器进行反序列化时遇到了向POJO的参数化构造函数注入外部值的问题。我提到了以下链接,但它们没有多大帮助 - Injecting ObjectMapper into a deserialized object using @JacksonInject and @JsonCreator How to pass constructor's parameters with jackson?
我有一个班级,比如说A扩展了BaseClass。
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.stereotype.Repository;
@Repository
@JsonInclude(Include.NON_NULL)
public class A extends BaseClass {
private String contentType;
private String size;
private String data;
/**
*
* @return
*/
public String getData() {
return data;
}
/**
*
* @param data
*/
public void setData(String data) {
this.data = data;
}
/**
*
* @return
*/
public String getContentType() {
return contentType;
}
/**
*
* @param contentType
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
*
* @param size
*/
public void setSize(String size) {
this.size = size;
}
}
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Component;
@Component
public abstract class BaseClass {
private String id;
/**
*
* @return
*/
public String getId() {
return id;
}
/**
*
* @param id
*/
public void setId(String id) {
this.id = id;
}
}
我的输入Json -
{
"data": {
"object" : [
{
"id" : "1234",
"contentType" : "text",
"size" : "1024",
"data" : "testdata"
},
{
"id" : "123",
"contentType" : "text",
"size" : "1024",
"data" : "testdata"
},
{
"id" : "342",
"contentType" : "text",
"size" : "1024",
"data" : "testdata"
}
]
}
}
我有一个GetJsonMessage类,我将这个A对象列表转换为自定义类AList,它扩展了ArrayList类。我有其他类似于A的类,因此在AList中使用泛型。
import com.fasterxml.jackson.annotation.JacksonInject;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.RecoverableDataAccessException;
import org.springframework.stereotype.Component;
@Component
public class AList<T extends BaseClass> extends ArrayList {
@JacksonInject
private String key;
public AList(@JacksonInject final String key){
this.key = key;
}
public AList(){}
/**
* Searches objects in DB
*
* @return List of BaseClass
*
*/
public List<BaseClass> search() throws Exception {
..........
}
}
现在GetJsonMessage类 -
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Component;
@Component
public class GetJsonMessage<T extends BaseClass> {
private Map<String, List<T>> data = new HashMap<>();
@JsonIgnore
private final ObjectMapper mapper = new ObjectMapper();
@JsonIgnore
private final InjectableValues.Std injectableValues = new InjectableValues.Std();
/**
*
* @return
*/
public Map<String, List<T>> getData() {
return data;
}
/**
*
* @param data
*/
public void setData(Map<String, List<T>> data) {
this.data = data;
}
/**
*
* @param key
* @param value
*/
public void setData(String key, List<T> value) {
this.data.put(key, value);
}
/**
*
* @param aClass
* @return
* @throws IOException
*/
public AList<T> getObjectList(String key, Class<? extends BaseClass> aClass) throws IOException {
injectableValues.addValue(String.class, key);
mapper.setInjectableValues(injectableValues);
AList<T> aList = mapper.readValue(mapper.writeValueAsString(data.get(key)), mapper.getTypeFactory().constructCollectionType(AList.class, aClass));
return aList;
}
}
最后我的控制器 -
public JsonResponse searchObjects(@RequestBody GetJsonMessage<A> jsonMessage,
@RequestParam Map<String, String> query) throws Exception {
AList<A> aList = jsonMessage.getObjectList("object", A.class);
aList.search();
}
当我执行时,我没有看到&#34; key&#34;设置进入AList类,也没有例外。
但是,如果我尝试通过将代码更改为下面来注入A类中的键,则会出现错误 -
错误:com.fasterxml.jackson.databind.JsonMappingException:没有 &#39; injectableValues&#39;配置后,无法使用id注入值 [java.lang.String中]
@Repository
@JsonInclude(Include.NON_NULL)
public class A extends BaseClass {
private String contentType;
private String size;
private String data;
private String key;
@JsonCreator
public A(@JacksonInject final String key){
this.key = key;
}
public A(){}
/**
*
* @return
*/
public String getData() {
return data;
}
/**
*
* @param data
*/
public void setData(String data) {
this.data = data;
}
/**
*
* @return
*/
public String getKey() {
return key;
}
/**
*
* @param data
*/
public void setKey(String key) {
this.key= key;
}
/**
*
* @return
*/
public String getContentType() {
return contentType;
}
/**
*
* @param contentType
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
*
* @param size
*/
public void setSize(String size) {
this.size = size;
}
}
无论哪种方式,我都无法将此外部属性注入到AList或A的构造函数中。
我使用的是jackson版本2.1.1
我不想使用CustomDeserializer,因为它不适合我有多个继承BaseClass的对象。
任何帮助将不胜感激。提前谢谢。