Json payload java callout

Hi,

Seeking some guidance on what would be the best approach. Basically I need to extract a json payload on my java callout and validate it against our own custom validator. The json payload is a list of phone numbers. each phone has a number and extension.

The main challenge i am facing is deserializing the json into my object. after hours of googling I found that apigee prohibits the use of reflections. I was trying to use Gson to do the deserialize.

Code snippet

public ExecutionResult execute(MessageContext messageContext, ExecutionContext executionContext) {
    try {
        String phonesAsString = messageContext.getVariable("phoneList").toString();
        messageContext.setVariable("PHONES_CONTENT_A", phonesAsString);
        Gson gson = new Gson();
        Phones phones = gson.fromJson(phonesAsString, Phones.class);
        ...
    }
    catch(Exception e) {
        ...     
    }
}

Phones & Phone class

private ArrayList<Phone> phoneList;
~~~~
/** The number. */
private String number;
/** The extension. */
private Integer extension;

Json payload

{
   "phoneList":[
      {
         "number":"+12232222222",
         "extension":1234
      },
      {
         "number":"+12232222222",
         "extension":1234
      }
   ]
}
Solved Solved
0 1 475
1 ACCEPTED SOLUTION

after hours of googling I found that apigee prohibits the use of reflections.

Yes. I'm sorry it took so much trouble to discover that. That's frustrating. We try to construct the Java callout runtime so that it emits a proper error message to give you a good hint when something fails. And examining the stacktrace of the Exception thrown can help with that. It usually looks like this:

java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
 at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
 at java.security.AccessController.checkPermission(AccessController.java:884)
 at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
 at com.apigee.securitypolicy.InternalSecurityManager.checkPermission(InternalSecurityManager.java:85)
 at java.lang.Class.checkMemberAccess(Class.java:2348)
 at java.lang.Class.getDeclaredConstructor(Class.java:2177)
 at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:101)
 at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:85)
 at com.google.gson.internal.bind.MapTypeAdapterFactory.create(MapTypeAdapterFactory.java:127)
 at com.google.gson.Gson.getAdapter(Gson.java:458)
 at com.google.gson.Gson.fromJson(Gson.java:931)
 at com.google.gson.Gson.fromJson(Gson.java:870)
  ...

But sometimes it's hard to figure out.

To answer your question, I think you can avoid the problem if you use a smaller, less ambitious parser that does not use reflection. That means parsing a generic Map, not a tightly bound class like "Person" or "PhoneList".

This repo shows you more:

https://github.com/DinoChiesa/ApigeeEdge-Java-Json-Parse

View solution in original post

1 REPLY 1

after hours of googling I found that apigee prohibits the use of reflections.

Yes. I'm sorry it took so much trouble to discover that. That's frustrating. We try to construct the Java callout runtime so that it emits a proper error message to give you a good hint when something fails. And examining the stacktrace of the Exception thrown can help with that. It usually looks like this:

java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
 at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
 at java.security.AccessController.checkPermission(AccessController.java:884)
 at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
 at com.apigee.securitypolicy.InternalSecurityManager.checkPermission(InternalSecurityManager.java:85)
 at java.lang.Class.checkMemberAccess(Class.java:2348)
 at java.lang.Class.getDeclaredConstructor(Class.java:2177)
 at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:101)
 at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:85)
 at com.google.gson.internal.bind.MapTypeAdapterFactory.create(MapTypeAdapterFactory.java:127)
 at com.google.gson.Gson.getAdapter(Gson.java:458)
 at com.google.gson.Gson.fromJson(Gson.java:931)
 at com.google.gson.Gson.fromJson(Gson.java:870)
  ...

But sometimes it's hard to figure out.

To answer your question, I think you can avoid the problem if you use a smaller, less ambitious parser that does not use reflection. That means parsing a generic Map, not a tightly bound class like "Person" or "PhoneList".

This repo shows you more:

https://github.com/DinoChiesa/ApigeeEdge-Java-Json-Parse