How Do I make a HTTP Delete/Update Request? - java

Right Now I have a Restful Web service called Users.java, That fake adds a user to a fake database
#Path("/users")
public class UsersService {
#POST
public Response handlePost(String requestBody) {
addUserToDatabase(requestBody);
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("status", "success");
jsonMap.put("resource-uri", "/users/12"); // assume 12 is the ID of the user we pretended to create
Gson gson = new Gson();
return Response.status(200).entity(gson.toJson(jsonMap)).build();
}
private boolean addUserToDatabase(String requestBody) {
Gson gson = new Gson();
Map<String, String> user = gson.fromJson(requestBody, new TypeToken<Map<String, String>>() {
}.getType());
for (String key : user.keySet()) {
System.out.println(key + ": " + user.get(key));
}
return true; // lie and say we added the user to the database
}
}
it is called using the Post request here, these are examples
public HttpResponse postRequest(String relativePath, Map<String, String> map){
try {
String fullPath = buildURL(relativePath);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost getRequest = new HttpPost(fullPath);
Gson gson = new Gson();
String postEntity = gson.toJson(map);
getRequest.setEntity(new StringEntity(postEntity));
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
httpClient.getConnectionManager().shutdown();
return response;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// POST
Map<String, String> map = new HashMap<>();
map.put("username", "Bill");
map.put("occupation", "Student");
map.put("age", "22");
map.put("DOB", "" + new Date(System.currentTimeMillis()));
HttpResponse response = client.postRequest("/api/users", map);
client.printResponse(response);
Now I want to do something similar with Delete and Update but dont know where to start any help would be great

Use appropriate #Path, #Delete and #Putannotations and implement the methods in a similar way you did for #Post.

Related

Authorization for Google Drive Push Notifications for Java

I am trying to get push notifications from a resource on Google Drive to my server. I have been looking at this example:
https://developers.google.com/drive/v3/web/push
And I have tried translating that to Java into something like this:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id", "36d00d08-000d-4723-91bc-a1a6ec302e59");
map.add("type", "web_hook");
map.add("address", "https://mydomain.appspot.com/rest/drive");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity(uri, request, String.class);
I have previously been using Googles libs for Drive to access files. In those cases I didn't need to create the request in such a "manual" way. I have used the class GoogleAuthorizationCodeFlow with a token to authorize my requests. I'm not sure how I should do that with RestTemplate. I am guessing that I need to do something like:
headers.set("Authorization", X);
What should X be here? Is that even the right way to approach authorization?
Edit:
Here is my attempt by reading a secret. The result is HTTP 401:
#Override
public String startListening() throws IOException {
final String fileId = "omitted";
String uri = "https://www.googleapis.com/drive/v3/files/" + fileId + "/watch";
HttpHeaders headers = getHeaders(getSecret());
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(getProperties(), headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(uri, request, String.class);
return response.getStatusCode() + " " + response.getBody() + " " + response.getHeaders();
}
private static HttpHeaders getHeaders(String theString) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + theString);
return headers;
}
private static MultiValueMap<String, String> getProperties() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id", "some uid");
map.add("type", "web_hook");
map.add("address", "https://mydomain.appspot.com/rest/drive");
return map;
}
private static String getSecret() throws IOException {
InputStream in =
ConcreteDriveListenerFactory.class.getResourceAsStream("/drive_secret.json");
StringWriter writer = new StringWriter();
IOUtils.copy(in, writer, "UTF-8");
return writer.toString();
}
As #DalmTo has mentioned, X is for token. With regard to sample POST request for Drive API try this code snippet from this SO thread. It also uses a POST method.
public static void main(String argv[]) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost(
"https://www.googleapis.com/drive/v2/files");
post.addHeader("Content-Type", "application/json");
post.addHeader("Authorization",
"Bearer XXXXXXXXXXXXXXXXXXXXXXXXX");
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("title", "Test folder");
jsonObject
.addProperty("mimeType", "application/vnd.google-apps.folder");
post.setEntity(new StringEntity(jsonObject.toString()));
httpClient.execute(post);
}

IBM MF8 Adapter Mashup - POST Requests

I tried a sample for post requests in IBM MF8 Java adapter.
Inside this adapter, I am trying to to call another Java adapter, SampleAdapter and want to do a POST with userDetails as parameter
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/balanced")
#OAuthSecurity(enabled = false)
public JSONObject generate(UserDetails userDetails , HttpRequest request, HttpSession session) throws UnsupportedEncodingException {
String messages = null;
String getProcedureURL = "/SampleAdapter/resource";
StringEntity requestEntity = new StringEntity(userDetails.toString(),ContentType.APPLICATION_JSON);
HttpPost httpPost = new HttpPost(getProcedureURL);
httpPost.setEntity(requestEntity);
JSONObject jsonObj = null;
HttpResponse response;
try {
response = adaptersAPI.executeAdapterRequest(httpPost);
jsonObj = adaptersAPI.getResponseAsJSON(response);
messages = (String)jsonObj.get("subscriptionMessage");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JSONObject json = new JSONObject();
json.put("value", messages);
return json;
}
SampleAdapter has to get the object userDetails. So that I can use it in the back end for some operations.
But, here I am unable to get the data into SampleAdapter. Also, I tried returning some String from SampleAdapter.
I get the below error
{"responseText":"","error":"Response cannot be parsed to JSON"}
I know that IBM MF does the json conversion internally, but here how is it possible to do a POST from one adapter to adapter.
I see samples given only for GET requests.
Any suggestions to do for POST?
I wrote you a short example based on yours:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/balanced")
#OAuthSecurity(enabled = false)
public JSONObject generate() throws UnsupportedEncodingException {
String messages = null;
String getProcedureURL = "/SampleAdapter/resource/hello";
StringEntity requestEntity = new StringEntity("world", ContentType.APPLICATION_JSON);
HttpPost httpPost = new HttpPost(getProcedureURL);
httpPost.setEntity(requestEntity);
JSONObject jsonObj = null;
HttpResponse response;
try {
response = adaptersAPI.executeAdapterRequest(httpPost);
jsonObj = adaptersAPI.getResponseAsJSON(response);
messages = "Hello " + (String)jsonObj.get("name");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JSONObject json = new JSONObject();
json.put("value", messages);
return json;
}
And here is the POST endpoint:
#POST
#Produces(MediaType.APPLICATION_JSON)
#Path("/hello")
#OAuthSecurity(enabled = false)
public Map<String, String> hello(String name) {
Map<String, String> result = new HashMap<String, String>();
result.put("name", name);
return result;
}
I hope this will help you.

How to use Spring RestTemplate instead of Apache Httpclient?

I want to use Spring RestTemplate instead of Apache HttpClient for working with a remote API
With HttpClient
// build request JSON
JSONObject json = new JSONObject();
json.put("username", username);
json.put("serial", serial);
json.put("keyId", keyId);
json.put("otp", otp);
String json_req = json.toString();
// make HTTP request and get response
HttpPost request = new HttpPost(AuthServer);
request.setHeader("Content-Type", "application/json");
request.setEntity(new StringEntity(json_req));
response = client.execute(request);
With RestTemplate
Map<String, String> paramMap = new HashMap<String,String>();
paramMap.put("username", userName);
paramMap.put("serial", serial);
paramMap.put("keyId", keyId);
paramMap.put("otp", otp);
String mapAsJson = new ObjectMapper().writeValueAsString(paramMap);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<String>(mapAsJson,requestHeaders);
try {
ResponseEntity<String> response = restTemplate.exchange(AuthServer, HttpMethod.POST, request, String.class);
return response.getHeaders();
} catch (HttpClientErrorException e) {
return null;
}
}
The code with HttpClient works but that with RestTemplate does not. I don't know how to use StringEntity in RestTemplate.
Spring version is 3.0.0, and JVM is 1.6.
RestTemplate is better suited to working with objects. As an example:
AuthenticationRequest.java
class AuthenticationRequest {
private String username;
private String serial;
private String key;
private String otp;
}
AuthenticationResponse.java
class AuthenticationResponse {
private boolean success;
}
AuthenticationCall.java
class AuthenticationCall {
public AuthenticationResponse execute(AuthenticationRequest payload) {
HttpEntity<AuthenticationRequest> request = new HttpEntity<AuthenticationRequest>(payload, new HttpHeaders());
return restTemplate.exchange("http://www.domain.com/api/endpoint"
, HttpMethod.POST
, request
, AuthenticationResponse.class).getBody();
}
}
These classes can be used as follows:
if(new AuthenticationCall().execute(authenticationRequest).isSuccess()) {
// Authentication succeeded.
}
else {
// Authentication failed.
}
All of this requires there to be a JSON library such as Jackson or GSON on the classpath.

Android: from DefaultHttpClient to Retrofit

I am struggling in finding a replacement for the deprecated DefaultHttpClient and connected classes liken HttpPost etc.
In a first attempt, I tried using the volley library, but nothing seemed to work, so after a bit research I am trying now with Retrofit 1.9.
In my app, I connect to a own restful client. Here is the old code (example POST), which works perfectly well:
private static DefaultHttpClient httpClient = new DefaultHttpClient();
public static String executePOST(Map<String, String> postParams, int connTO, int sockTO, String uri){
String res, message;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, connTO);
HttpConnectionParams.setSoTimeout(httpParams, sockTO);
HttpConnectionParams.setTcpNoDelay(httpParams, true);
httpClient.setParams(httpParams);
HttpPost httppost = new HttpPost(uri);
JSONObject json = new JSONObject();
try {
Iterator<Entry<String, String>> iterator = postParams.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<String, String> pair = (Map.Entry<String, String>)iterator.next();
json.put(pair.getKey(), pair.getValue());
}
message = json.toString();
httppost.setEntity(new StringEntity(message, "UTF8"));
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Content-type", "application/json");
HttpResponse response = httpClient.execute(httppost);
HttpEntity entity = response.getEntity();
res = EntityUtils.toString(entity).trim();
} catch (ClientProtocolException e) {
res = "Client Protocol Exception";
} catch (IOException e) {
res = e.getLocalizedMessage();
} catch (JSONException e){
res = e.getLocalizedMessage();
}
return res;
}
I send the request like this from my Activity
Map<String, String> arguments = new HashMap<String, String>();
arguments.put("email", username);
new HttpClient(arguments, new LoginActivityCommunicationListener(this, LoginOperation.EMAIL_CHECK), URI_ROOT + "/kunde", 0).execute();
The listener in the arguments handles the response callback, the 0 means POST.
this results in a JSON response, having the fields id and person
So I tried to implement a Retrofit variant of above like this
MyApi.java
public interface MyDosAPI {
#FormUrlEncoded
#POST("/kunde")
public void checkEmail(#Field("email") String email, Callback<EmailCheck> response);
}
EmailCheck.java
public class EmailCheck {
#SerializedName("id")
private String id;
#SerializedName("person")
private String person;
public void setId(String id){
this.id = id;
}
public void setPerson(String person){
this.person = person;
}
public String getId(){
return id;
}
public String getPerson(){
return person;
}
}
and in the activity
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(URI_ROOT)
.build();
MyDosAPI api = adapter.create(MyDosAPI.class);
api.checkEmail(username, new Callback<EmailCheck>() {
#Override
public void success(EmailCheck emailChecks, Response response) {
Log.i("MyCount", "success");
}
#Override
public void failure(RetrofitError error) {
Log.i("MyCount", error.getMessage());
}
});
result
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
obviously there is something essential that I am missing. Is there - apart of Retrofit or Volley - another solution where I can define the requests like I did before?
Change to:
public interface MyDosAPI {
#POST("/kunde")
public void checkEmail(#Body String email, Callback<EmailCheck> response);
}

Spring restTemplate issue in getting response

My rest server is generating response when I called it with rest client software. When I call it with resttemplate code mentioned above, then server generates response(print logs) but resttemplate does nothing(no next line executes after call) and prints internal error.
This is the method in my server
#ResponseBody
public ResponseEntity<Map<String, Object>> name(){......
...
return new ResponseEntity<Map<String, Object>>(messagebody, HttpStatus.OK);
}
This is the way I am calling it through restTemplate
ResponseEntity<Map> response1 = restTemplate.getForEntity(finalUrl.toString(), Map.class);
Try to use ParameterizedTypeReference instead of wildcarded Map.
It should looks like this.
ParameterizedTypeReference<Map<String, Object>> typeRef = new ParameterizedTypeReference<Map<String, Object>>() {};
ResponseEntity<Map<String, Object>> response = restTemplate.exchange(finalUrl.toString(), HttpMethod.GET, null, typeRef);
this is a example that works for me
#RequestMapping(value = "/getParametros/{instancia}", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<String> getParametros(#PathVariable String instancia)
{
LOG.debug("REST. Obteniendo parametros del servidor " + instancia);
Map<String, String> mapa = parametrosService.getProperties(instancia);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=UTF-8");
headers.add("X-Fsl-Location", "/");
headers.add("X-Fsl-Response-Code", "302");
ObjectMapper mapper = new ObjectMapper();
String s = "";
try
{
s = mapper.writeValueAsString(mapa);
} catch (JsonProcessingException e)
{
LOG.error("NO SE PUEDE MAPEAR A JSON");
}
if (mapa == null)
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
return new ResponseEntity<String>(s, headers, HttpStatus.OK);
}
you can Catch the HttpStatusCodeException from which you can get response in String .
below code works for me.
restTemplate.postForObject( url, jsonRequest, ResponseData.class );
catch( HttpStatusCodeException codeException )
{
String payload = codeException.getResponseBodyAsString();
System.out.println( payload );
}

Categories

Resources