001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.http.converter.json; 018 019import java.io.Reader; 020import java.io.Writer; 021import java.lang.reflect.ParameterizedType; 022import java.lang.reflect.Type; 023 024import javax.json.bind.Jsonb; 025import javax.json.bind.JsonbBuilder; 026import javax.json.bind.JsonbConfig; 027 028import org.springframework.lang.Nullable; 029import org.springframework.util.Assert; 030 031/** 032 * Implementation of {@link org.springframework.http.converter.HttpMessageConverter} 033 * that can read and write JSON using the 034 * <a href="http://json-b.net/">JSON Binding API</a>. 035 * 036 * <p>This converter can be used to bind to typed beans or untyped {@code HashMap}s. 037 * By default, it supports {@code application/json} and {@code application/*+json} with 038 * {@code UTF-8} character set. 039 * 040 * @author Juergen Hoeller 041 * @since 5.0 042 * @see javax.json.bind.Jsonb 043 * @see javax.json.bind.JsonbBuilder 044 * @see #setJsonb 045 */ 046public class JsonbHttpMessageConverter extends AbstractJsonHttpMessageConverter { 047 048 private Jsonb jsonb; 049 050 051 /** 052 * Construct a new {@code JsonbHttpMessageConverter} with default configuration. 053 */ 054 public JsonbHttpMessageConverter() { 055 this(JsonbBuilder.create()); 056 } 057 058 /** 059 * Construct a new {@code JsonbHttpMessageConverter} with the given configuration. 060 * @param config the {@code JsonbConfig} for the underlying delegate 061 */ 062 public JsonbHttpMessageConverter(JsonbConfig config) { 063 this.jsonb = JsonbBuilder.create(config); 064 } 065 066 /** 067 * Construct a new {@code JsonbHttpMessageConverter} with the given delegate. 068 * @param jsonb the Jsonb instance to use 069 */ 070 public JsonbHttpMessageConverter(Jsonb jsonb) { 071 Assert.notNull(jsonb, "A Jsonb instance is required"); 072 this.jsonb = jsonb; 073 } 074 075 076 /** 077 * Set the {@code Jsonb} instance to use. 078 * If not set, a default {@code Jsonb} instance will be created. 079 * <p>Setting a custom-configured {@code Jsonb} is one way to take further 080 * control of the JSON serialization process. 081 * @see #JsonbHttpMessageConverter(Jsonb) 082 * @see #JsonbHttpMessageConverter(JsonbConfig) 083 * @see JsonbBuilder 084 */ 085 public void setJsonb(Jsonb jsonb) { 086 Assert.notNull(jsonb, "A Jsonb instance is required"); 087 this.jsonb = jsonb; 088 } 089 090 /** 091 * Return the configured {@code Jsonb} instance for this converter. 092 */ 093 public Jsonb getJsonb() { 094 return this.jsonb; 095 } 096 097 098 @Override 099 protected Object readInternal(Type resolvedType, Reader reader) throws Exception { 100 return getJsonb().fromJson(reader, resolvedType); 101 } 102 103 @Override 104 protected void writeInternal(Object object, @Nullable Type type, Writer writer) throws Exception { 105 if (type instanceof ParameterizedType) { 106 getJsonb().toJson(object, type, writer); 107 } 108 else { 109 getJsonb().toJson(object, writer); 110 } 111 } 112 113}