405 error code while calling from Jersey REST client - java

I am requesting for put operation and after request performed I am redirecting to GET service URL.Here, I am facing the issue of 405 HTTP error code. However, same code works for me in the case of POST operation.
Below code is EndPoint:
#PUT
#Produces({ MediaType.APPLICATION_JSON })
public Response put(InputStream objInputStream) {
// System.out.println("AckService.put()");
String strOutput = "";
Status objStatus = Status.OK;
URI objRedirectionURI = null;
try {
this.submitRequest(objInputStream);
objRedirectionURI = new URI("https://local.test.com:8443/Reply/fetch");
System.err.println("\n\nredirecting the put request...... to get operation\n\n");
return Response.seeOther(objRedirectionURI).build();
} catch (Exception e) {
e.printStackTrace();
objStatus = Status.INTERNAL_SERVER_ERROR;
}
}
Client:
ClientResponse response = null;
try {
response = objWebResource.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON)
.put(ClientResponse.class, strInputData);
}catch (Exception e) {
blnIsOk = false;
if(null != e.getMessage())
lstExceptionMessage.add(e.getMessage());
e.printStackTrace();
}
Please let me know how I can resolve this.

In that question I think you can find the answer:
PUT-POST Rest Information

Related

Response status code showing 200 for gateway error (504)

I have a REST endpoint which call another API which take a while to process and returning 504 error when I verify through Rest client (Insomnia). But in my service I see this transaction as success 200 not 504.
Below is how my code snippet:
public ResponseEntity<Customer> processResponse(Customer customer, String restUri) {
ResponseEntity<Customer> response;
String customerJson = null;
try {
RestTemplate restTemplate = restTemplateBuilder.basicAuthorization(userName, password).build();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Customer> entity = new HttpEntity<>(customer, headers);
CustomerJson = jacksonUtil.toJSON(customer);
response = restTemplate.exchange(restUri, HttpMethod.PUT, entity, Customer.class);
if (response.getStatusCode().is2xxSuccessful()) {
logger.info("Return success from the server");
} else {
logger.error("Error while getting the response from the server");
}
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
return response;
}
What am I missing here? Why its not executing the else block?
Thanks in advance.
Your method seems to be returning null response in case of error. Can you check if you have done any handling in caller and passing 200 from controller layer itself.

Changing a 404 response for REST API to a 200 empty response

I have a Spring Boot application written in Java that is a REST API. This service (Svc A) calls a REST API service (Svc B) with is also a Spring Boot Application written in Java. Svc B returns a 404 status code when no data was found. I need to change this response to a 200 status code and return an empty response object. I am not sure if or how to do this.
I can catch the error and determine if the 404 is this no data found error. However, I don't know how to change the response to a 200 empty response.
I am using a FeignClient to call the service. This is the error code that catches the 404:
#Component
public class FeignErrorDecoder implements ErrorDecoder {
Logger logger = LoggerFactory.getLogger(this.getClass());
#Override
public Exception decode(String methodKey, Response response) {
Reader reader = null;
String messageText = null;
switch (response.status()){
case 400:
logger.error("Status code " + response.status() + ", methodKey = " + methodKey);
case 404:
{
logger.error("Error took place when using Feign client to send HTTP Request. Status code " + response.status() + ", methodKey = " + methodKey);
try {
reader = response.body().asReader();
//Easy way to read the stream and get a String object
String result = CharStreams.toString(reader);
logger.error("RESPONSE BODY: " + result);
ObjectMapper mapper = new ObjectMapper();
//just in case you missed an attribute in the Pojo
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//init the Pojo
ExceptionMessage exceptionMessage = mapper.readValue(result,
ExceptionMessage.class);
messageText = exceptionMessage.getMessage();
logger.info("message: " + messageText);
} catch(IOException ex) {
logger.error(ex.getMessage());
}
finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return new ResponseStatusException(HttpStatus.valueOf(200), messageText);
}
default:
return new Exception(response.reason());
}
}
}
I can change the status code to a 200 and it returns a 200 but I need to the response to have an empty response object.
The above code will return this response body of an error response object:
{
"statusCd" : "200",
"message" : "The Location not found for given Location Number and Facility Type Code",
"detailDesc" : "The Location not found for given Location Number and Facility Type Code. Error Timestamp : 2020-01-31 18:19:13"
}
I need it to return a response body like this:
200 - Empty Response
{
"facilityNumber": "923",
"facilityTimeZone": null,
"facilityAbbr": null,
"scheduledOperations": []
}
In case 404 just try
return new ResponseStatusException(HttpStatus.valueOf(200));
For anyone that has to do something this crazy...here is my solution:
Removed the FeignErrorCode file.
Added an exception to ControllerAdvice class like this:
#ExceptionHandler(FeignException.class)
public ResponseEntity<?> handleFeignException(FeignException fe, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), HttpStatus.valueOf(fe.status()), fe.getMessage(), request.getDescription(false));
String response = fe.contentUTF8();
if(response != null) {
ScheduledOperationsViewResponse scheduledOperationsViewResponse = new ScheduledOperationsViewResponse();
if (response.contains("Scheduled") || response.contains("Location")) {
HttpHeaders headers = new HttpHeaders();
scheduledOperationsViewResponse.setFacilityNumber(request.getParameter("facilityNumber"));
return new ResponseEntity<ScheduledOperationsViewResponse>(scheduledOperationsViewResponse, headers, HttpStatus.OK);
}
}
return new ResponseEntity<>(errorDetails, errorDetails.getStatus());
}

RestEasy Client giving could not find writer for content-type application/xml type

I am writing a test client for my endpoint, but it is not able to execute the connection giving
EXCEPTION : could not find writer for content-type application/xml type: com.gepower.gees.ifs.goet.porequest.model.CreatePOReq
in the line
ClientResponse<CreatePOResp> clientResponse = client.post(CreatePOResp.class);
From Postman, the endpoint is returning the result fine.
I have tried to add all the RestEasy jars in my project, but it is still giving the same error while
public static CreatePOResp createUpdateALFPO(CreatePOReq req) {
CreatePOResp response = new CreatePOResp();
String operation = "createUpdatePO";
try {
String xmlReq = "";
try {
xmlReq = XmlUtils.marshalXmlToString(req);
System.out.println(operation + " - XML SOAP REQUEST: " + xmlReq);
} catch (Exception xmlex) {
System.out.println(xmlex.getMessage());
}
ClientRequest client = new ClientRequest("http://localhost/ofsrestws/fs/porequest/addpo");
client.body(MediaType.APPLICATION_XML, req);
System.out.println("URI ====" + client.getUri());
ClientResponse<CreatePOResp> clientResponse = client.post(CreatePOResp.class);
ResteasyProviderFactory.getInstance().addBuiltInMessageBodyReader(new JAXBXmlTypeProvider());
if (clientResponse.getStatus() == 200) {
response = clientResponse.getEntity();
System.out.println("web service is OK");
return response;
} else {
System.out.println("an issue has occure during the call of the web service: "
+ clientResponse.getResponseStatus());
// Object resp = clientResponse.getResponseStatus();
return null;
}
} catch (NullPointerException e) {
System.out.println("EXCEPTION : " + e.getMessage());
return null;
} catch (Exception e) {
System.out.println("EXCEPTION : " + e.getMessage());
return null;
} finally {}
}
The stacktrace:
java.lang.RuntimeException: could not find writer for content-type application/xml type: com.gepower.gees.ifs.goet.porequest.model.CreatePOReq
at org.jboss.resteasy.client.ClientRequest.writeRequestBody(ClientRequest.java:409)
at org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor$ClientRequestEntity.<init>(ApacheHttpClientExecutor.java:117)
at org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor.loadHttpMethod(ApacheHttpClientExecutor.java:188)
at org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor.execute(ApacheHttpClientExecutor.java:56)
at org.jboss.resteasy.client.ClientRequest.execute(ClientRequest.java:378)
at org.jboss.resteasy.client.ClientRequest.httpMethod(ClientRequest.java:590)
at org.jboss.resteasy.client.ClientRequest.post(ClientRequest.java:496)
at org.jboss.resteasy.client.ClientRequest.post(ClientRequest.java:501)
at org.tcs.TestJava.createUpdateALFPO(TestJava.java:52)
at org.tcs.TestJava.main(TestJava.java:31)
Please find the list of dependencies
The only thing I can see is that you register the adapter after you make the post request:
ClientResponse<CreatePOResp> clientResponse = client.post(CreatePOResp.class);
ResteasyProviderFactory.getInstance().addBuiltInMessageBodyReader(new JAXBXmlTypeProvider());
Since the exception occurs in the post call, maybe you should try switching the order.
I notice that you are using the deprecated RestEasy client API. Note that the JAX-RS 2.0 client implementation will automatically load all available
Provider classes (through the service loader mechanism). Maybe you should consider using that API instead.

ResponseBody inconsistent JSON string (OKHttp 3.10.0)

Firstly I searched about this issue but couldn't find any solution.
I am sending a POST request to a web service. This web service returns response but I see that the response is not complete.
With PostMan I get full response without issue. But OKHttp cuts the response.
public List<Product> getProducts(String token, long bill_acct_id, long customer_id, Context context) {
if(token != null && !token.equals("")) {
Gson gson = new Gson();
List<Product> prods;
Map<String, String> list_of_headers = new HashMap<>();
list_of_headers.put("WSC-AUTH-TOKEN", token);
list_of_headers.put("Accept", "application/json, text/plain, */*");
list_of_headers.put("Content-Type", "application/json");
Headers headers = Headers.of(list_of_headers);
try {
Response response = RequestSender.post2("URL", "{\"billingAccountId\":\""+bill_acct_id+"\", \"customerId\":\""+customer_id+"\"}", headers, context);
int returnCode = response.code();
ResponseBody body = response.body();
Log.e("INFO", body.string());
if (returnCode == 200) {
prods = gson.fromJson(body.string(), new TypeToken<List<Product>>() {
}.getType());
return prods;
}
} catch (Exception ex) {
Log.e("Error", ex.getMessage());
ex.printStackTrace();
}
}
return null;
}
The response:
Solved.
Response from Postman:
Solved
Anyone faced this issue? I need your help. Thanks.
**EDIT: ** Actually it was complete. Log.e() and System.out.println(); methods doesn't show complete JSON.

POST request to REST service in AsyncTask

I'm writing some small android application that works with REST services.
The base structure of the response is:
{
result: "ok/error",
message: "some string",
entity: "either object or error description"
}
The entity type is different each time whether the response is ok or error.
Now, I'm calling the service from AsyncTask and I need to return the result to the UI thread.
I'm using gson library to desirialize the JSON from the server. The problem is that I do not have the ability to know what type of response I've got (ok or error).
Also, the AsyncTask can return only single type to the UI thread. Below is an example for what I could come up with. I need to state that I'm not a java programmer and I may not know all the patterns and maybe I miss something.
Anyway, I'll be glad for any help.
public class RegisterProxyAsync extends AsyncTask<User, String, Object> {
#Override
protected Object doInBackground(User... params) {
try {
Gson gson = new Gson();
String request = gson.toJson(params[0]);
HttpClient client = new DefaultHttpClient();
HttpPost postAction = new HttpPost("http://SomeServiceEndpoint/register");
postAction.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
postAction.setEntity(new StringEntity(request));
HttpResponse response = client.execute(postAction);
if (response != null) {
InputStream stream = response.getEntity().getContent();
String strResult = CharStreams.toString(new InputStreamReader(stream));
try {
UserResponse userResponse = gson.fromJson(strResult, UserResponse.class);
return userResponse;
} catch (Exception e) {
ErrorResponse errorResponse = gson.fromJson(strResult, ErrorResponse.class);
return errorResponse;
}
Log.e("debug", strResult);
}
} catch (Exception e) {
// TODO:Handle exception
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object result) {
// TODO: execute some work
}
}
EDIT:
I've changed the server to return proper HttpCodes (200 for success, 400 for error) but, I still have the problem of returning two different types of object from the doinbackground method, one for error and another for success.
A proper REST service should include an HTTP response code indicating the status of the processed request. If you have control over the service then I would recommend altering it to return a variant of 40x or 50x codes, to signal that an error has occurred. The service should only return a 200 OK if the request succeeded. On your client side, you would then parse the response based on the status code (normal entity for 200 ok, error entity for anything else). Pseudocode:
if(response.getStatusLine().getStatusCode() == 200) {
UserResponse userResponse = gson.fromJson(strResult, UserResponse.class);
} else {
ErrorResponse errorResponse = gson.fromJson(strResult, ErrorResponse.class);
}
If you can't change the server side for whatever reason, then on your client side you will have to use a generic JsonObject to parse the response. Pseudocode:
JSONObject jsonObj = new JSONObject(strResult);
if("ok".equals(jsonObj.get("result")) {
return gson.fromJson(jsonObj.toString(), UserResponse.class);
} else {
return gson.fromJson(jsonObj.toString(), ErrorResponse.class);
}

Categories