Domino REST Service - Can't get parameter from GET Call - rest

I can't seem to get json handed into a GET call in the serviceBean.
<xe:restService id="restService1" pathInfo="getaccount">
<xe:this.service>
<xe:customRestService requestContentType="application/json" serviceBean="web.service.GetAccount" contentType="application/json"/>
</xe:this.service>
</xe:restService>
For the pathInfo I've tried pathInfo="getaccount", pathInfo="getaccount/{id}", pathInfo="getaccount{id}"
The serviceBean:
public class GetAccount extends CustomServiceBean {
#Override
public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {
XspOpenLogUtil.logEvent(null, "getAccount()", Level.INFO, null);
Map parameters = engine.getHttpRequest().getParameterMap();
XspOpenLogUtil.logEvent(null, "getAccount() - getHttpRequest().getParameterMap(): " + parameters.toString(), Level.INFO, null);
String json_string = IOUtils.toString(engine.getHttpRequest().getInputStream(), "UTF-8");
XspOpenLogUtil.logEvent(null, "getAccount() - jsonReaderString: " + json_string, Level.INFO, null); }
I can get the json_string if I change to a POST, but I should be able to perform a GET and send some json in i.e. { "id": "1234" }
Using SoapUI with the resource as api.xsp/getaccount{id} and a parameter Name=id and Value=1234
Thanks,
Scott.

I figured it out. You can use the engine.getHttpRequest().getRequestURI(), which will give you the URI handed in e.g. api.nsf/api.xsp/getaccount/Bob.Smith%40mail.com. Run a URLDecode to cleanup the encoding.
Hope this helps others trying to sort this out.
Scott.

Related

Callback function issues in FB.API for Unity

I am using Unity 5.5.2f1 pro and facebook's SDK v 7.9.4
I have a script which after login (managed in a previous scene) sends an API request to FB asking for friends, name and email and sends that info as a POST to a php website.
code:
[Serializable]
public struct FBData {
public string first_name;
public string email;
public string friends;
public string id;}
public class UserManagement : MonoBehaviour {
string urlSaveUserData="some php website";
public Text testTxt;
FBData parsedData;
// Use this for initialization
void Start () {
//Check if it's the first time the user is opening the app.
if (UserInfo.FIRST_TIME) {
//update text (only used for testing, should be removed in production.)
testTxt.text = "Your user id is: " + UserInfo.ID;
//Perform FB.API call to get User Data.
getUserData ();
//Save in SQL table. (won't get here if line in getUserData() is active)
StartCoroutine ("saveUserData");
} else {
//do something else.
}
note: Since this is meant for iOS I have to test it on a device so I'm using text in the screen to display info (think of it as a badly implemented print statement).
The problem: In my callback function for FB.API I write in the text Gameobject (aka testTxt) the parsed information from the response which is saved in the Custom UserInfo clss. It display's correctly but the code gets stuck there. It doesn't continue to the next function. HOWEVER, if I delete/comment that line and don't display anything in the text field. The codes does continue to the POST function BUT the information from the API call is not passed, i.e my custom class is empty (leading me to believe the callback function is not called at all).
public void getUserData(){
string query = "me?fields=first_name,email,friends";
FB.API (query, HttpMethod.GET, Apicallback, new Dictionary<string, string> ());
}
private void Apicallback(IGraphResult result){
//Parse Graph response into a specific class created for this result.
parsedData = JsonUtility.FromJson<FBData>(result.RawResult);
//Pass each field into UserInfo class.
UserInfo.EMAIL = parsedData.email;
UserInfo.FRIENDS = parsedData.friends;
UserInfo.NAME = parsedData.first_name;
UserInfo.FACEBOOKID = parsedData.id;
/*problem area, if I comment line below, then previous information is apparently not stored. If left as is then testTxt displays correct information but code gets stuck there. */
testTxt.text = "This is the info from USerInfoInside the APICallback: " + UserInfo.EMAIL + UserInfo.FRIENDS + UserInfo.FACEBOOKID;
}
The function below is to send info to php website, is there for illustrative purposes:
code:
public IEnumerator saveUserData() {
//get user info (this information is EMPTY if line in getUserData() is commented.
parsedData.id = UserInfo.FACEBOOKID;
parsedData.friends = UserInfo.FRIENDS;
parsedData.first_name = UserInfo.NAME;
parsedData.email = UserInfo.EMAIL;
//translate data into json
string JsonBodyData = JsonUtility.ToJson (parsedData);
//Custom web request (POST method doesnt seem to work very well, documentation example sends empty form)
var w = new UnityWebRequest(urlSaveUserData, "POST");
byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(JsonBodyData);
w.uploadHandler = (UploadHandler) new UploadHandlerRaw(bodyRaw);
w.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();
w.SetRequestHeader("Content-Type", "application/json");
yield return w.Send();
//work with received data...}
Im stuck here any help is appreciated. Thanks!
Be sure to use EscapeURL when using strings directly for JSON or HTTP POST and GET methods. The lack of this treatment tends to screw things over, particulary in iOS platforms.
From what I can see, this code
string query = "me?fields=first_name,email,friends";
should instead be escaped as
string query = WWW.EscapeURL("me?fields=first_name,email,friends");
so characters like "?" won't get encoded as an URL symbol.
I'm assuming you don't need to do that for your illustrative example, because UnityWebRequest already escapes your POST request strings internally, but I can't fully confirm that.

HttpResponseException: Internal Server Error

Weirdest thing I have seen in a while. I run my API call through Postman and have no problems at all making a GET request. However, the groovy code below pulls groovyx.net.http.HttpResponseException: Internal Server Error. I am not able to pull even debug to understand if I am actually getting a 5xx error or my code is legitimately broken.
Additionally I have had code like this work in the past, I re-pulled that working code and have the same error. Curious if my Maven config settings would be causing the issue as well (Not sure where I would have to debug). I have also tried messing with the URIbuilder line to see if changing the endpoints would help.
Thanks for helping
abstract class HTTTPClient {
protected runGetRequest(String endpointPassedIn, RESTClient Client){
URIBuilder myEndpoint = new URIBuilder(new URI(Client.uri.toString() + endpointPassedIn))
//Error happens at the next Line
Client.get(uri: myEndpoint, contentType: ContentType.JSON)
LazyMap Response = unprocessedResponse.getData() as LazyMap
return Response
}
}
#Singleton(lazy = true)
class RequestService extends HTTTPClient {
private String auth = "myAuth"
private String baseURL = 'https://api.endpoint.net/'
private RESTClient client = setClient(baseURL, auth)
public buildResponseList(int pagesToPull) {
String endpoint = 'site/address.json?page='
ArrayList responseList = []
for (int i = 1; i <= pagesToPull; i++) {
LazyMap Response = runGetRequest(endpoint + i, client)
for (row in Response) {
responseList.add(row)
//TODO Add in items call here
}
}
return conversationList
}
The error was due to encoding in the Authorization, was on the server side, not the code side

How to transform PageRequest object to query string?

I'm writing an RESTful API which consumes another RESTful Data API, and I'm using Spring Data.
The client side send the page request using query params like:
http://api.mysite.com/products?page=1&size=20&sort=id,asc&sort=name,desc
And I transform the params to PageRequest object and transfer it to the Service Layer.
In the service, I would like to use TestTemplate to interact with the Data API which use a URL, and How can I transform the PageRequest object to a query string like
page=1&size=20&sort=id,asc&sort=name,desc
then I can request data like:
restTemplate.getForEntity("http://data.mysite.com/products?page=1&size=20&sort=id,asc&sort=name,desc",String.class)
I know I am a bit late on this answer, but I too was not able to found an already implemented way to do this. I ended up developing my own routine for doing this:
public static String encodeURLComponent(String component){
try {
return URLEncoder.encode(component, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("You are dumm enough that you cannot spell UTF-8, are you?");
}
}
public static String queryStringFromPageable(Pageable p){
StringBuilder ans = new StringBuilder();
ans.append("page=");
ans.append(encodeURLComponent(p.getPageNumber() + ""));
// No sorting
if (p.getSort() == null)
return ans.toString();
// Sorting is specified
for(Sort.Order o : p.getSort()){
ans.append("&sort=");
ans.append(encodeURLComponent(o.getProperty()));
ans.append(",");
ans.append(encodeURLComponent(o.getDirection().name()));
}
return ans.toString();
}
It is not complete, there probably are a couple of details that I am missing, but for my user case (and I think for most of them) this works.
you can pass as new :
new PageRequest(int page,int size)
And in repository layer you can write as:
Page<User> findByName(String name,Pageable page)
in place of Pageable page you have to pass new PageRequest(int page,int size)
For ascending order you can refer this:
List<Todo> findByTitleOrderByTitleAsc(String title);
I think you just need to iterate through the request parameters from your other API request, and then pass all the parameters values into the new Url for a new API request.
sudo code could be:
//all query params can be found in Request.QueryString
var queryParams = Request.QueryString;
private string ParseIntoQuery(NameValueCollection values)
{
//parse the identified parameters into a query string format
// (i.e. return "?paramName=paramValue&paramName2=paramValue2" etc.)
}
in your code, you will then do this:
restTemplate.getForEntity(urlAuthority + ParseIntoQuery(Request.QueryString));
simple as that. Hope that answers?
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl("http://data.mysite.com/products");
addRequestParam(uriComponentsBuilder, "page", pageable.getPageNumber());
addRequestParam(uriComponentsBuilder, "size", pageable.getPageSize());
String uri = uriComponentsBuilder.toUriString() + sortToString(pageable.getSort());
addRequestParam method:
private static void addRequestParam(UriComponentsBuilder uriBuilder, String parameterName, Object parameter) {
if (parameter != null) {
uriBuilder.queryParam(parameterName, parameter);
}
}
implement sortToString(Sort sort) method as #Shalen. You have to obtain something like this: &sort=name,asc&sort=name2,desc. Return "" if Sort is null;

How would I receive all fields from a dynamic form with Struts?

I found myself with the following problem:
I have a page generated with logic:iterate that shows the current supervisor and assistant of a service.
That page also acts as a form where people can add their possible substitutes, but you never know how many of those are there.
Due to the environment I am currently working with it had to be without JSTL so a lot of options were gone; couldn't get DynaActionForm working for this either.
Since I couldn't find anything but I already got the answer I decided to create this to answer anyone who might have the same issue.
Code:
public ActionForward post(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
String[] tot;
try {
Enumeration<?> fieldsForm = request.getParameterNames();
while(fieldsForm.hasMoreElements()) {
String current = (String) fieldsForm.nextElement();
tot = request.getParameterValues(current);
System.out.println("Field name is: " + current);
for (i=0; i<tot.length; i++) {
// do whatever you need to do; contents are in tot[i]
System.out.println("Value " + i + " is: " + tot[i]);
}
}
catch (Exception ex) {
ex.printStackTrace();
System.err.println(ex.getMessage());
}
}

Update records using Salesforce REST API - Patch method not working

I'm trying to update a record residing in salesforce table. Im using the Java HttpClient REST API to do the same. Getting an error when we use PATCH to update a record in Salesforce.
PostMethod post = new PostMethod(
instanceUrl + "/services/data/v20.0/sobjects/" +
objectName + "/" + Id + "?_HttpMethod=PATCH"
);
[{"message":"HTTP Method 'PATCH' not allowed. Allowed are HEAD,GET,POST","errorCode":"METHOD_NOT_ALLOWED"}]
Also tried doing the following:
PostMethod post = new PostMethod(
instanceUrl + "/services/data/v20.0/sobjects/" + objectName + "/" + Id)
{
public String getName() { return "PATCH";
}
};
This also returns the same error. We are using apache tomcat with commons-httpclient-3.1.jar library. Please advise on how this can be done.
Please check if you you're using the right implementation of PATCH method, see: Insert or Update (Upsert) a Record Using an External ID.
Also check if your REST URL is correct, probably your objectId is not passed in correctly from Javascript.
The ObjectName is the Name of an Salesforce table i.e. 'Contact'. And Id is the Id of a specific record you want to update in the table.
Similar:
Can I update without an ID?
for Drupal: How to deal with SalesforceException: HTTP Method 'PATCH' not allowed. Allowed are HEAD,GET,POST
As I think you're aware, commons httpclient 3.1 does not have the PATCH method, and the library has been end-of-lifed. In your code above, you're trying to add the HTTP method as a query parameter, which doesn't really make sense.
As seen on SalesForce Developer Board, you can do something like this instead:
HttpClient httpclient = new HttpClient();
PostMethod patch = new PostMethod(url) {
#Override
public String getName() {
return "PATCH";
}
};
ObjectMapper mapper = new ObjectMapper();
StringRequestEntity sre = new StringRequestEntity(mapper.writeValueAsString(data), "application/json", "UTF-8");
patch.setRequestEntity(sre);
httpclient.executeMethod(patch);
This allows you to PATCH without switching out your httpclient library.
I created this method to send the patch request via the Java HttpClient class.
I am using JDK V.13
private static VarHandle Modifiers; // This method and var handler are for patch method
private static void allowMethods(){
// This is the setup for patch method
System.out.println("Ignore following warnings, they showed up cause we are changing some basic variables.");
try {
var lookUp = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
Modifiers = lookUp.findVarHandle(Field.class, "modifiers", int.class);
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
try {
Field methodField = HttpURLConnection.class.getDeclaredField("methods");
methodField.setAccessible(true);
int mods = methodField.getModifiers();
if (Modifier.isFinal(mods)) {
Modifiers.set(methodField, mods & ~Modifier.FINAL);
}
String[] oldMethods = (String[])methodField.get(null);
Set<String> methodsSet = new LinkedHashSet<String>(Arrays.asList(oldMethods));
methodsSet.addAll(Collections.singletonList("PATCH"));
String[] newMethods = methodsSet.toArray(new String[0]);
methodField.set(null, newMethods);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}