POST request using Spring RestTemplate with XML body as String - java

I need to make a rest call to share a post in Linkedin and I am using Spring Social Linkedin module for that. Unfortunately I cannot simply use
org.springframework.social.linkedin.api.NetworkUpdateOperations.share(NewShare share)
method, I am working on a project that provides the raw rest template to the users, and users can make any rest call to any url using it. I am using Spring Social's Linkedin module just for the authentication part (and it works as it should).
So, I provide to users the rest template behind the Linkedin Spring Social Linkedin module. And they should be able to post a share to Linkedin with a given url and data in runtime. The request body should contain something like this (taken from here):
<share>
<comment>Check out the LinkedIn Share API!</comment>
<content>
<title>LinkedIn Developers Documentation On Using the Share API</title>
<description>Leverage the Share API to maximize engagement on user-generated content on LinkedIn</description>
<submitted-url>https://developer.linkedin.com/documents/share-api</submitted-url>
<submitted-image-url>http://m3.licdn.com/media/p/3/000/124/1a6/089a29a.png</submitted-image-url>
</content>
<visibility>
<code>anyone</code>
</visibility>
</share>
To share, I create a String with that xml and use the command postForObject. Like this:
String toShare = "<share><comment>Check out..." // the string of xml
Object result = linkedinRestTemplate.postForObject("https://api.linkedin.com/v1/people/~/shares", toShare, Object.class);
But this call fails with a response 400 Bad Request. It seems like rest template handling this xml string and not as an object, so it is not serialized and put to the request body properly.
Spring Social Linkedin does the same thing but only with a difference: It has a serializable class called NewShare which have the same structure of that xml. But when an instance of the NewShare is given as body to the request, it is successful. Like this:
NewShare share = new NewShare();
share.set... // set its properties, sub-classes, content etc.
Object result = linkedinRestTemplate.postForObject("https://api.linkedin.com/v1/people/~/shares", newShare, Object.class);
This call is successful.
But I cannot deserialize my String into NewShare because I am providing an API so I assume I have absolutely no information about the request body.
So how can I manage to make spring handle the string xml body correctly and make a proper service call?

Related

How to change routes url based on request body in spring cloud

I want to route requests based on some values in requestBody in spring cloud, for example:
if value of firstField in requestBody is chagre, I want to route this request to /chagre api
else if value of firstField in requestBody is package, I want to route this request to /package api
Any help would be appreciated.
Best practice is not to route according to request body, but use different attributes of the HTTP request instead. Spring Cloud Gateway includes many built-in route predicate factories based on those attributes.
The problem is request body can be read only once. moreover you need to know the object class it contains in order to properly read it.
In order to construct a solution to your question, we can use Spring Cloud Gateway ModifyRequestBody to rewrite the request body after you read it and before it send to the downstream.
Read more about ModifyRequestBody

How to make Spring Boot API accept a client's custom 'x-www-form-urlencoded' format for the nested objects parsing

The Spring boot API could not parse the x-www-form-urlencoded type request since the client posted the data differently than what Java supports.
The incoming request body looks like below:
DeliveryPostCode=TEST123000&EnableCOD=false&Basket%5B0%5D%5BId%5D=383293820&Basket%5B0%5D%5BCategory%5D=Smartphone
In which a Basket is an object which has Id, Category as fields.
Decoding the above URL gives -
DeliveryPostCode=TEST123000&EnableCOD=false&Basket[0][Id]=383293820&Basket[0][Category]=Smartphone
which does not work for Java
If we can get a request which looks like below, It works for Java -
DeliveryPostCode=TEST123000&EnableCOD=false&Basket[0].Id=383293820&Basket[0].Category=Smartphone
Since the client is something which we cannot afford to change. We have to do some manipulation in Java before Controller takes this
OR
a modify in middleware node js layer we have between client & server which acts as a proxy.
Please suggest.

Save oauth/token body into Java object

After I successfully run the request to http://IP:port/oauth/ token to get the authorization token from oauth using spring framework, the response body looks something like this:
{
access_token = jsjxjdnjf .... some_acces_token,
token_type: bearer,
(....) more fields
}
The client to acces this endpoint is a simple Java app using org.springframework.web.client.RestTeplate
My question is:
Is there a predefined class that allows me to encapsulate(map) that information and access it through getters?
Or I have to implement it myself, which would look like this:
public class OauthTokeWrapper {
private String access_token;
(...)//getters,constructors...
}
It is not recommended to read access tokens in the OAuth Client, which should just treat the token as an opaque string to be sent to APIs. Access tokens are not always JWT format and reading tokens in the client could lead to future problems.
Instead it is typical to work with the API claims in a back end API. One option for doing this is via the Nimbus libraries. Here is some example API code of mine in case useful.

Error handling: different response format for REST API and web pages

I'm adding some web pages and associated controllers to an existing REST API project.
In the existing project error handling is implementing via a #ControllerAdvice class, having several specific #ExceptionHandler methods and a custom ErrorController implementation (to customize default error controller provided by Spring Boot).
As expected, all these methods are returning error data in JSON, so every time an error occurs I'm receiving a JSON object as response, even in (web) controllers.
I'd like to distinguish among API errors and "web" errors. Or it could be better to generate response in a consistent format according to request format.
Which is the common way to acheve this? Should I implement different error handling for API and web areas or should I simply verify request format?
Can you provide any example?
It's easy using JSON views. Assuming the method returns a ModelAndView, if it's a web request you return a regular view (= a web page):
ModelAndView modelAndView = new ModelAndView("myView");
If it's a REST request (or AJAX request) you return a JSON view:
MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
jsonView.setExtractValueFromSingleKeyModel(true);
ModelAndView modelAndView = new ModelAndView(jsonView);
modelAndView.addObject(myResponseObject);
In this case Spring does not return a page, but a JSON response that represents the object that you provided.

How to obtain data from a webservice in a JSF action method?

I'm trying to determine the correct API calls on FacesContext to do the following when processing a backing bean action:
Within the action method construct a URL of dynamic parameters
Send the constructed URL to service
Parse the returned service response parameters
Continue with action method processing based on reponse string from request.
Any suggestions on the highlevel API calls for steps 2 and 3 to send me in the right direction would be very appreicated. Note, the service I'm calling is external to this application in a blackbox. Instructions are: send URL in specified format, parse response to see what happened.
This problem is not specific to JSF in particular, so you'll find nothing in JSF API. The standard Java API offers java.net.URL or, which allows more fine grained control, java.net.URLConnection to fire HTTP requests and obtain the response as an InputStream which you can then freely parse the usual Java way.
InputStream response = new URL("http://google.com").openStream();
// ...
Depending on the content type of the response, there may be 3rd party API's which ease the parsing. For example, Google Gson if it's JSON or Jsoup if it's HTML/XML.

Categories

Resources