2323import com .fasterxml .jackson .databind .MappingJsonFactory ;
2424import com .fasterxml .jackson .databind .ObjectMapper ;
2525import com .fasterxml .jackson .databind .node .ValueNode ;
26- import com . rabbitmq . tools . json . JSONReader ;
27- import com . rabbitmq . tools . json . JSONWriter ;
26+ import org . slf4j . Logger ;
27+ import org . slf4j . LoggerFactory ;
2828
2929import java .io .IOException ;
3030import java .lang .reflect .Method ;
3333import java .util .Map ;
3434
3535/**
36+ * {@link JsonRpcMapper} based on Jackson.
37+ * Uses the streaming and databind modules.
3638 *
39+ * @see JsonRpcMapper
40+ * @since 5.4.0
3741 */
3842public class JacksonJsonRpcMapper implements JsonRpcMapper {
3943
44+ private static final Logger LOGGER = LoggerFactory .getLogger (JacksonJsonRpcMapper .class );
45+
4046 private final ObjectMapper mapper ;
4147
4248 public JacksonJsonRpcMapper (ObjectMapper mapper ) {
@@ -62,7 +68,21 @@ public JsonRpcRequest parse(String requestBody, ServiceDescription description)
6268 if ("method" .equals (name )) {
6369 method = parser .getValueAsString ();
6470 } else if ("id" .equals (name )) {
65- // FIXME parse id, can be any type (handle only primitive and wrapper)
71+ TreeNode node = parser .readValueAsTree ();
72+ if (node instanceof ValueNode ) {
73+ ValueNode idNode = (ValueNode ) node ;
74+ if (idNode .isNull ()) {
75+ id = null ;
76+ } else if (idNode .isTextual ()) {
77+ id = idNode .asText ();
78+ } else if (idNode .isNumber ()) {
79+ id = Long .valueOf (idNode .asLong ());
80+ } else {
81+ LOGGER .warn ("ID type not null, text, or number {}, ignoring" , idNode );
82+ }
83+ } else {
84+ LOGGER .warn ("ID not a scalar value {}, ignoring" , node );
85+ }
6686 } else if ("version" .equals (name )) {
6787 version = parser .getValueAsString ();
6888 } else if ("params" .equals (name )) {
@@ -80,6 +100,10 @@ public JsonRpcRequest parse(String requestBody, ServiceDescription description)
80100 throw new JsonRpcMappingException ("Error during JSON parsing" , e );
81101 }
82102
103+ if (method == null ) {
104+ throw new IllegalArgumentException ("Could not find method to invoke in request" );
105+ }
106+
83107 List <Object > convertedParameters = new ArrayList <>(parameters .size ());
84108 if (!parameters .isEmpty ()) {
85109 ProcedureDescription proc = description .getProcedure (method , parameters .size ());
@@ -102,69 +126,40 @@ public JsonRpcRequest parse(String requestBody, ServiceDescription description)
102126 );
103127 }
104128
105- protected Object convert (TreeNode node , Class <?> expectedType ) throws IOException {
106- Object value ;
107- if (expectedType .isPrimitive ()) {
108- ValueNode valueNode = (ValueNode ) node ;
109- if (expectedType == Boolean .TYPE ) {
110- value = valueNode .booleanValue ();
111- } else if (expectedType == Character .TYPE ) {
112- value = valueNode .textValue ().charAt (0 );
113- } else if (expectedType == Short .TYPE ) {
114- value = valueNode .shortValue ();
115- } else if (expectedType == Integer .TYPE ) {
116- value = valueNode .intValue ();
117- } else if (expectedType == Long .TYPE ) {
118- value = valueNode .longValue ();
119- } else if (expectedType == Float .TYPE ) {
120- value = valueNode .floatValue ();
121- } else if (expectedType == Double .TYPE ) {
122- value = valueNode .doubleValue ();
123- } else {
124- throw new IllegalArgumentException ("Primitive type not supported: " + expectedType );
125- }
126- } else {
127- value = mapper .readValue (node .traverse (), expectedType );
128- }
129- return value ;
130- }
131-
132129 @ Override
133130 public JsonRpcResponse parse (String responseBody , Class <?> expectedReturnType ) {
134131 JsonFactory jsonFactory = new MappingJsonFactory ();
135132 Object result = null ;
133+ JsonRpcException exception = null ;
134+ Map <String , Object > errorMap = null ;
136135 try (JsonParser parser = jsonFactory .createParser (responseBody )) {
137136 while (parser .nextToken () != null ) {
138137 JsonToken token = parser .currentToken ();
139138 if (token == JsonToken .FIELD_NAME ) {
140139 String name = parser .currentName ();
141- parser .nextToken ();
142140 if ("result" .equals (name )) {
141+ parser .nextToken ();
143142 if (expectedReturnType == Void .TYPE ) {
144143 result = null ;
145144 } else {
146145 result = convert (parser .readValueAsTree (), expectedReturnType );
147146 }
147+ } else if ("error" .equals (name )) {
148+ errorMap = (Map <String , Object >) convert (parser .readValueAsTree (), Map .class );
149+ exception = new JsonRpcException (
150+ errorMap .toString (),
151+ (String ) errorMap .get ("name" ),
152+ errorMap .get ("code" ) == null ? 0 : (Integer ) errorMap .get ("code" ),
153+ (String ) errorMap .get ("message" ),
154+ errorMap
155+ );
148156 }
149157 }
150158 }
151159 } catch (IOException e ) {
152160 throw new JsonRpcMappingException ("Error during JSON parsing" , e );
153161 }
154- Map <String , Object > map = (Map <String , Object >) (new JSONReader ().read (responseBody ));
155- Map <String , Object > error ;
156- JsonRpcException exception = null ;
157- if (map .containsKey ("error" )) {
158- error = (Map <String , Object >) map .get ("error" );
159- exception = new JsonRpcException (
160- new JSONWriter ().write (error ),
161- (String ) error .get ("name" ),
162- error .get ("code" ) == null ? 0 : (Integer ) error .get ("code" ),
163- (String ) error .get ("message" ),
164- error
165- );
166- }
167- return new JsonRpcResponse (map , result , map .get ("error" ), exception );
162+ return new JsonRpcResponse (result , errorMap , exception );
168163 }
169164
170165 @ Override
@@ -175,4 +170,31 @@ public String write(Object input) {
175170 throw new JsonRpcMappingException ("Error during JSON serialization" , e );
176171 }
177172 }
173+
174+ protected Object convert (TreeNode node , Class <?> expectedType ) throws IOException {
175+ Object value ;
176+ if (expectedType .isPrimitive ()) {
177+ ValueNode valueNode = (ValueNode ) node ;
178+ if (expectedType == Boolean .TYPE ) {
179+ value = valueNode .booleanValue ();
180+ } else if (expectedType == Character .TYPE ) {
181+ value = valueNode .textValue ().charAt (0 );
182+ } else if (expectedType == Short .TYPE ) {
183+ value = valueNode .shortValue ();
184+ } else if (expectedType == Integer .TYPE ) {
185+ value = valueNode .intValue ();
186+ } else if (expectedType == Long .TYPE ) {
187+ value = valueNode .longValue ();
188+ } else if (expectedType == Float .TYPE ) {
189+ value = valueNode .floatValue ();
190+ } else if (expectedType == Double .TYPE ) {
191+ value = valueNode .doubleValue ();
192+ } else {
193+ throw new IllegalArgumentException ("Primitive type not supported: " + expectedType );
194+ }
195+ } else {
196+ value = mapper .readValue (node .traverse (), expectedType );
197+ }
198+ return value ;
199+ }
178200}
0 commit comments