mirror of
https://github.com/apache/struts.git
synced 2026-08-07 07:37:20 +00:00
WW-4650 Json deserialization does not work in 2.5.1
logic need to be changed as accept can be a list; the check need to be done in the list itself. Accept:application/json, text/plain, */*
This commit is contained in:
@@ -11,6 +11,9 @@
|
||||
.metadata/
|
||||
Servers/
|
||||
|
||||
#VSCode
|
||||
.vscode
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ public class JSONInterceptor extends AbstractInterceptor {
|
||||
accept = request.getHeader("accept");
|
||||
}
|
||||
|
||||
String[] accepts = accept.split(",");
|
||||
|
||||
Object rootObject = null;
|
||||
final ValueStack stack = invocation.getStack();
|
||||
if (this.root != null) {
|
||||
@@ -92,96 +94,98 @@ public class JSONInterceptor extends AbstractInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
if ((accept != null) && accept.equalsIgnoreCase("application/json")) {
|
||||
// load JSON object
|
||||
Object obj = JSONUtil.deserialize(request.getReader());
|
||||
|
||||
// JSON array (this.root cannot be null in this case)
|
||||
if(obj instanceof List && this.root != null) {
|
||||
String mapKey = this.root;
|
||||
rootObject = null;
|
||||
|
||||
if(this.root.indexOf('.') != -1) {
|
||||
mapKey = this.root.substring(this.root.lastIndexOf('.') + 1);
|
||||
|
||||
rootObject = stack.findValue(this.root.substring(0, this.root.lastIndexOf('.')));
|
||||
if (rootObject == null) {
|
||||
throw new RuntimeException("JSON array: Invalid root expression: '" + this.root + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
// create a map with a list inside
|
||||
Map m = new HashMap();
|
||||
m.put(mapKey, new ArrayList((List) obj));
|
||||
obj = m;
|
||||
}
|
||||
|
||||
if (obj instanceof Map) {
|
||||
Map json = (Map) obj;
|
||||
|
||||
// clean up the values
|
||||
if (dataCleaner != null)
|
||||
dataCleaner.clean("", json);
|
||||
|
||||
if (rootObject == null) // model overrides action
|
||||
rootObject = invocation.getStack().peek();
|
||||
|
||||
// populate fields
|
||||
populator.populateObject(rootObject, json);
|
||||
} else {
|
||||
LOG.error("Unable to deserialize JSON object from request");
|
||||
throw new JSONException("Unable to deserialize JSON object from request");
|
||||
}
|
||||
} else if ((accept != null) && accept.equalsIgnoreCase("application/json-rpc")) {
|
||||
Object result;
|
||||
if (this.enableSMD) {
|
||||
for (String accept : accepts) {
|
||||
if ((accept != null) && accept.equalsIgnoreCase("application/json")) {
|
||||
// load JSON object
|
||||
Object obj = JSONUtil.deserialize(request.getReader());
|
||||
|
||||
if (obj instanceof Map) {
|
||||
Map smd = (Map) obj;
|
||||
// JSON array (this.root cannot be null in this case)
|
||||
if(obj instanceof List && this.root != null) {
|
||||
String mapKey = this.root;
|
||||
rootObject = null;
|
||||
|
||||
if (rootObject == null) { // model makes no sense when using RPC
|
||||
rootObject = invocation.getAction();
|
||||
if(this.root.indexOf('.') != -1) {
|
||||
mapKey = this.root.substring(this.root.lastIndexOf('.') + 1);
|
||||
|
||||
rootObject = stack.findValue(this.root.substring(0, this.root.lastIndexOf('.')));
|
||||
if (rootObject == null) {
|
||||
throw new RuntimeException("JSON array: Invalid root expression: '" + this.root + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
// invoke method
|
||||
try {
|
||||
result = this.invoke(rootObject, smd);
|
||||
} catch (Exception e) {
|
||||
RPCResponse rpcResponse = new RPCResponse();
|
||||
rpcResponse.setId(smd.get("id").toString());
|
||||
rpcResponse.setError(new RPCError(e, RPCErrorCode.EXCEPTION, getDebug()));
|
||||
// create a map with a list inside
|
||||
Map m = new HashMap();
|
||||
m.put(mapKey, new ArrayList((List) obj));
|
||||
obj = m;
|
||||
}
|
||||
|
||||
if (obj instanceof Map) {
|
||||
Map json = (Map) obj;
|
||||
|
||||
// clean up the values
|
||||
if (dataCleaner != null)
|
||||
dataCleaner.clean("", json);
|
||||
|
||||
if (rootObject == null) // model overrides action
|
||||
rootObject = invocation.getStack().peek();
|
||||
|
||||
// populate fields
|
||||
populator.populateObject(rootObject, json);
|
||||
} else {
|
||||
LOG.error("Unable to deserialize JSON object from request");
|
||||
throw new JSONException("Unable to deserialize JSON object from request");
|
||||
}
|
||||
} else if ((accept != null) && accept.equalsIgnoreCase("application/json-rpc")) {
|
||||
Object result;
|
||||
if (this.enableSMD) {
|
||||
// load JSON object
|
||||
Object obj = JSONUtil.deserialize(request.getReader());
|
||||
|
||||
if (obj instanceof Map) {
|
||||
Map smd = (Map) obj;
|
||||
|
||||
if (rootObject == null) { // model makes no sense when using RPC
|
||||
rootObject = invocation.getAction();
|
||||
}
|
||||
|
||||
// invoke method
|
||||
try {
|
||||
result = this.invoke(rootObject, smd);
|
||||
} catch (Exception e) {
|
||||
RPCResponse rpcResponse = new RPCResponse();
|
||||
rpcResponse.setId(smd.get("id").toString());
|
||||
rpcResponse.setError(new RPCError(e, RPCErrorCode.EXCEPTION, getDebug()));
|
||||
|
||||
result = rpcResponse;
|
||||
}
|
||||
} else {
|
||||
String message = "SMD request was not in the right format. See http://json-rpc.org";
|
||||
|
||||
RPCResponse rpcResponse = new RPCResponse();
|
||||
rpcResponse.setError(new RPCError(message, RPCErrorCode.INVALID_PROCEDURE_CALL));
|
||||
result = rpcResponse;
|
||||
}
|
||||
} else {
|
||||
String message = "SMD request was not in the right format. See http://json-rpc.org";
|
||||
String message = "Request with content type of 'application/json-rpc' was received but SMD is "
|
||||
+ "not enabled for this interceptor. Set 'enableSMD' to true to enable it";
|
||||
|
||||
RPCResponse rpcResponse = new RPCResponse();
|
||||
rpcResponse.setError(new RPCError(message, RPCErrorCode.INVALID_PROCEDURE_CALL));
|
||||
rpcResponse.setError(new RPCError(message, RPCErrorCode.SMD_DISABLED));
|
||||
result = rpcResponse;
|
||||
}
|
||||
} else {
|
||||
String message = "Request with content type of 'application/json-rpc' was received but SMD is "
|
||||
+ "not enabled for this interceptor. Set 'enableSMD' to true to enable it";
|
||||
|
||||
RPCResponse rpcResponse = new RPCResponse();
|
||||
rpcResponse.setError(new RPCError(message, RPCErrorCode.SMD_DISABLED));
|
||||
result = rpcResponse;
|
||||
String json = JSONUtil.serialize(result, excludeProperties, getIncludeProperties(),
|
||||
ignoreHierarchy, excludeNullProperties);
|
||||
json = addCallbackIfApplicable(request, json);
|
||||
boolean writeGzip = enableGZIP && JSONUtil.isGzipInRequest(request);
|
||||
JSONUtil.writeJSONToResponse(new SerializationParams(response, this.defaultEncoding,
|
||||
this.wrapWithComments, json, true, writeGzip, noCache, -1, -1, prefix, "application/json"));
|
||||
|
||||
return Action.NONE;
|
||||
} else {
|
||||
LOG.debug("Accept header parameter must be 'application/json' or 'application/json-rpc'. Ignoring request with accept ", accept);
|
||||
break;
|
||||
}
|
||||
|
||||
String json = JSONUtil.serialize(result, excludeProperties, getIncludeProperties(),
|
||||
ignoreHierarchy, excludeNullProperties);
|
||||
json = addCallbackIfApplicable(request, json);
|
||||
boolean writeGzip = enableGZIP && JSONUtil.isGzipInRequest(request);
|
||||
JSONUtil.writeJSONToResponse(new SerializationParams(response, this.defaultEncoding,
|
||||
this.wrapWithComments, json, true, writeGzip, noCache, -1, -1, prefix, "application/json"));
|
||||
|
||||
return Action.NONE;
|
||||
} else {
|
||||
|
||||
LOG.debug("Accept header parameter must be 'application/json' or 'application/json-rpc'. Ignoring request with accept ", accept);
|
||||
}
|
||||
|
||||
return invocation.invoke();
|
||||
|
||||
@@ -71,7 +71,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
private void tryBadJSON(String fileName) throws Exception {
|
||||
// request
|
||||
setRequestContent(fileName);
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -92,7 +92,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDDisabledSMD() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-3.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
SMDActionTest1 action = new SMDActionTest1();
|
||||
@@ -111,7 +111,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDAliasedMethodCall1() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-14.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -129,7 +129,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDAliasedMethodCall2() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-15.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -147,7 +147,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDNoMethod() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-4.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -171,7 +171,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDMethodWithoutAnnotations() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-9.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -192,7 +192,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDPrimitivesNoResult() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-6.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -227,7 +227,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDReturnObject() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-10.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -252,7 +252,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testSMDObjectsNoResult() throws Exception {
|
||||
// request
|
||||
setRequestContent("smd-7.txt");
|
||||
this.request.addHeader("accept", "application/json-rpc");
|
||||
this.request.addHeader("accept", "application/json-rpc, text/plain, */*");
|
||||
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
interceptor.setEnableSMD(true);
|
||||
@@ -300,7 +300,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void testReadEmpty() throws Exception {
|
||||
// request
|
||||
setRequestContent("json-6.txt");
|
||||
this.request.addHeader("accept", "application/json");
|
||||
this.request.addHeader("accept", "application/json, text/plain, */*");
|
||||
|
||||
// interceptor
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
@@ -315,7 +315,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
public void test() throws Exception {
|
||||
// request
|
||||
setRequestContent("json-1.txt");
|
||||
this.request.addHeader("accept", "application/json");
|
||||
this.request.addHeader("accept", "application/json, text/plain, */*");
|
||||
|
||||
// interceptor
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
@@ -437,7 +437,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
|
||||
public void testRoot() throws Exception {
|
||||
setRequestContent("json-5.txt");
|
||||
this.request.addHeader("accept", "application/json");
|
||||
this.request.addHeader("accept", "application/json, text/plain, */*");
|
||||
|
||||
// interceptor
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
@@ -462,7 +462,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
|
||||
public void testJSONArray() throws Exception {
|
||||
setRequestContent("json-12.txt");
|
||||
this.request.addHeader("accept", "application/json");
|
||||
this.request.addHeader("accept", "application/json, text/plain, */*");
|
||||
|
||||
// interceptor
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
@@ -488,7 +488,7 @@ public class JSONInterceptorTest extends StrutsTestCase {
|
||||
|
||||
public void testJSONArray2() throws Exception {
|
||||
setRequestContent("json-12.txt");
|
||||
this.request.addHeader("accept", "application/json");
|
||||
this.request.addHeader("accept", "application/json, text/plain, */*");
|
||||
|
||||
// interceptor
|
||||
JSONInterceptor interceptor = new JSONInterceptor();
|
||||
|
||||
Reference in New Issue
Block a user