Spring 自定義HttpMessageConverter實現MongoDb自定義ObjectId物件為字串
阿新 • • 發佈:2019-02-03
上週公司讓我做MongoDB的Document與json自定義相互轉換工作,具體就是
1.將後臺的Document直接返回給前臺,前臺接收到的是json資料,而且裡面的ObjectId是字串的形式:
“_id”:{ “$oid”: “598da5dd3888f020b164b25f” } 轉成 “_id”:”598da5dd3888f020b164b25f”
2.前臺傳入後臺的處理和上面相反:
_id”:”598da5dd3888f020b164b25f” 轉成 “_id”:{ “$oid”: “598da5dd3888f020b164b25f” }
其他都不變。
舉例來講:
前臺傳入的json字串:
{“name”:”張三111111”,”_id”:”598da5dd3888f020b164b25f”,”position”:”遼寧”,”age”:28}
後臺controller中:
@RequestMapping(value="/findone")
public Document findOne(@RequestBody Document document) throws Exception{
System.out.println("傳進來的Document-->"+document);
System.out.println("傳進來的Document.toJson--->"+document.toJson());
String collection = "hos_user_info" ;
String id = "598da5dd3888f020b164b25f";
Document doc = service.queryById(collection, id);
System.out.println("findOne(),doc.toString---->"+doc);
System.out.println("findOne(),doc.toJson()---->"+doc.toJson());
return doc;
}
直接用Document,接收入參,直接返回Document物件。同時前臺收到的是json字串,而且id是字串形式。
所以,此處就需要自定義json 的轉換器了:
1.自定義類DocumentHttpMessageConverter,繼承AbstractHttpMessageConverter。
具體程式碼:
public class DocumentHttpMessageConverter extends AbstractHttpMessageConverter<Document> {
private Logger logger = LoggerFactory.getLogger(DocumentHttpMessageConverter.class);
public DocumentHttpMessageConverter() {
super(new MediaType("application", "json", Charset.forName("UTF-8"))); //自定義的型別:application/json
}
@Override
protected boolean supports(Class<?> clazz) {
return Document.class.isAssignableFrom(clazz); //只支援Document物件
}
/**
* @Author
* @Date 9:58 八月 24 0024
* @Description: 讀取請求資料,構造Document物件,將輸入的json(ObjectId以字串形式)中"_id": "59915afa19191fcffc24a1d9" 改成: "_id": { "$oid": "59915afa19191fcffc24a1d9" }格式,以用於轉化成Document物件
*/
@Override
protected Document readInternal(Class<? extends Document> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
String inputjson = StreamUtils.copyToString(inputMessage.getBody(), Charset.forName("UTF-8"));
System.out.println("inputstream"+inputjson);
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(ObjectId.class, new ObjectIdDeserializer());
mapper.registerModule(module);
ObjectId oid = mapper.readValue(inputjson, ObjectId.class);
inputjson = inputjson.replace("\"" + oid.toString() + "\"", "{ \"$oid\": \"" + oid.toString() + "\" }");
System.out.println("輸入資料自動轉換>"+inputjson);
return Document.parse(inputjson);
}
/**
* @Author
* @Date 9:59 八月 24 0024
* @Description: 將Document轉化成json(ObjectId以字串形式)字串,輸出。去掉了ObjectId,由"_id" : ObjectId("598d5bb7791c00bbf615977a")改成了:"_id":"598d5bb7791c00bbf615977a"
*/
@Override
protected void writeInternal(Document document, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> docmap = new HashMap<String, Object>(16);
Iterator itdoc = document.entrySet().iterator();
while (itdoc.hasNext()) {
Document.Entry entry = (Document.Entry) itdoc.next();
Object value = entry.getValue();
if (value instanceof ObjectId) {
value = value.toString();
}
docmap.put((String) entry.getKey(), value);
}
String out = mapper.writeValueAsString(docmap);
System.out.println("writeInternal,78lines,out-->"+out);
outputMessage.getBody().write(out.getBytes("UTF-8"));
}
}
2.自定義ObjectId返序列化類ObjectIdDeserializer,繼承JsonDeserializer
public class ObjectIdDeserializer extends JsonDeserializer<ObjectId> {
@Override
public ObjectId deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
String oid = node.get("_id").asText();
System.out.println("反序列化:》"+oid);
return new ObjectId(oid);
}
}
3.配置spring檔案:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<!-- 增加自定義處理MongoDB 的Document 與 普通Json字串的轉換 -->
<bean class="com.converter.DocumentHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
這裡要特別注意下:
register-defaults=”false” 這個不用配置應該也可以,具體看專案