23
23
import com .fasterxml .jackson .databind .MappingJsonFactory ;
24
24
import com .fasterxml .jackson .databind .ObjectMapper ;
25
25
import 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 ;
28
28
29
29
import java .io .IOException ;
30
30
import java .lang .reflect .Method ;
33
33
import java .util .Map ;
34
34
35
35
/**
36
+ * {@link JsonRpcMapper} based on Jackson.
37
+ * Uses the streaming and databind modules.
36
38
*
39
+ * @see JsonRpcMapper
40
+ * @since 5.4.0
37
41
*/
38
42
public class JacksonJsonRpcMapper implements JsonRpcMapper {
39
43
44
+ private static final Logger LOGGER = LoggerFactory .getLogger (JacksonJsonRpcMapper .class );
45
+
40
46
private final ObjectMapper mapper ;
41
47
42
48
public JacksonJsonRpcMapper (ObjectMapper mapper ) {
@@ -62,7 +68,21 @@ public JsonRpcRequest parse(String requestBody, ServiceDescription description)
62
68
if ("method" .equals (name )) {
63
69
method = parser .getValueAsString ();
64
70
} 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
+ }
66
86
} else if ("version" .equals (name )) {
67
87
version = parser .getValueAsString ();
68
88
} else if ("params" .equals (name )) {
@@ -80,6 +100,10 @@ public JsonRpcRequest parse(String requestBody, ServiceDescription description)
80
100
throw new JsonRpcMappingException ("Error during JSON parsing" , e );
81
101
}
82
102
103
+ if (method == null ) {
104
+ throw new IllegalArgumentException ("Could not find method to invoke in request" );
105
+ }
106
+
83
107
List <Object > convertedParameters = new ArrayList <>(parameters .size ());
84
108
if (!parameters .isEmpty ()) {
85
109
ProcedureDescription proc = description .getProcedure (method , parameters .size ());
@@ -102,69 +126,40 @@ public JsonRpcRequest parse(String requestBody, ServiceDescription description)
102
126
);
103
127
}
104
128
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
-
132
129
@ Override
133
130
public JsonRpcResponse parse (String responseBody , Class <?> expectedReturnType ) {
134
131
JsonFactory jsonFactory = new MappingJsonFactory ();
135
132
Object result = null ;
133
+ JsonRpcException exception = null ;
134
+ Map <String , Object > errorMap = null ;
136
135
try (JsonParser parser = jsonFactory .createParser (responseBody )) {
137
136
while (parser .nextToken () != null ) {
138
137
JsonToken token = parser .currentToken ();
139
138
if (token == JsonToken .FIELD_NAME ) {
140
139
String name = parser .currentName ();
141
- parser .nextToken ();
142
140
if ("result" .equals (name )) {
141
+ parser .nextToken ();
143
142
if (expectedReturnType == Void .TYPE ) {
144
143
result = null ;
145
144
} else {
146
145
result = convert (parser .readValueAsTree (), expectedReturnType );
147
146
}
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
+ );
148
156
}
149
157
}
150
158
}
151
159
} catch (IOException e ) {
152
160
throw new JsonRpcMappingException ("Error during JSON parsing" , e );
153
161
}
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 );
168
163
}
169
164
170
165
@ Override
@@ -175,4 +170,31 @@ public String write(Object input) {
175
170
throw new JsonRpcMappingException ("Error during JSON serialization" , e );
176
171
}
177
172
}
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
+ }
178
200
}
0 commit comments