I'm working on a rest API where when post request is made by posting an XML file it should send the response 200 OK if the file is received successfully and 400 if the XML file is having any tag missing and 500 error if GET is used instead of POST. I am able to do the first two cases 200 and 400, not sure how to add 500 in the code. Am posting my code here, please suggest.
if (dataFile==null) {
try {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Failed to process content of file.");
}
catch (IOException e1) {
LOGGER.error("Failed to send response due to error:
" + e1.getMessage());
}
}
else{
response.setStatus(HttpServletResponse.SC_OK);
response.addHeader("Location", getResourceUri(dataFileMetadata,
request).toString());
It's pretty unclear from your code example what you're trying to do there,
but I would guess that you're talking about something like this:
#POST
#Path("/some/path")
#Consumes(MediaType.APPLICATION_XML)
public Response post(String someXML) {
try {
if (isMissingTag(someXML)) {
return Response.status(Status.BAD_REQUEST).entity("error message goes here").build();
}
// do stuff
return Response.ok().build();
} catch (Exception e) {
LOG.error("error message goes here", e);
return Response.serverError().entity("error message goes here").build();
}
}
You won't need to return anything if someone tries to hit your service with a GET, since you aren't publishing that as an endpoint in the first place.
I would highly suggest reading the jersey user guide if you're interested in writing restful web services.
Related
I am writing a personal web server.
When I send the GET request to the system, the system responds well.
But when I send the HEAD request, I get the following problems:
sun.net.httpserver.ExchangeImpl sendResponseHeaders
WARNING: sendResponseHeaders: being invoked with a content length for a HEAD
request java.io.IOException: response headers not sent yet at
jdk.httpserver/sun.net.httpserver.PlaceholderOutputStream.checkWrap(ExchangeImpl.java:448)
at
jdk.httpserver/sun.net.httpserver.PlaceholderOutputStream.write(ExchangeImpl.java:458)
at
ir.utux.service.HandleHttpResponse.writeResponse(HandleHttpResponse.java:32)
This is the code I wrote to manage the response, to simplify HEAD and GET together.
public void writeResponse(SettingModal settingModal) {
try {
switch (requestHeader.getMethod()) {
case HEAD,GET -> {
response.getResponseHeaders().set("Server", "utux HttpServer");
response.getResponseHeaders().set("Connection", "close");
response.getResponseHeaders().set("Transfer-encoding", "chunked");
response.getResponseHeaders().set("Content-Type", ContentType.HTML);
response.sendResponseHeaders(HttpStatus.SC_OK, "".length());
response.getResponseBody().write("".getBytes(StandardCharsets.UTF_8));
response.getResponseBody().flush();
response.getResponseBody().close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
I found the problem
BODY should not be sent in response to HEAD requests.
I am trying to access REST API using OauthClient
try {
OAuthClient client = new OAuthClient(new URLConnectionClient());
OAuthResourceResponse response = client.resource(request, OAuth.HttpMethod.POST, OAuthResourceResponse.class);
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
The api call returns a response body when I execute the call using Postman, but when I use this code above, it throws exception and I can not see the response body, in order to parse it.
Here is the exception:
org.apache.oltu.oauth2.common.exception.OAuthSystemException: java.io.IOException: Server returned HTTP response code: 409 for URL:
Is it possible to parse the response body for 4xx errors
You can build your response object in catch block and return like
} catch (Exception ex) {
return Response.status(Response.Status.BAD_REQUEST).entity(new PresenterClass(ex.getMessage())).build();
}
Using Presenter class constructor
Public PresenterClass(String errorMessage){
this.message = errorMessage;
}
I am using javax.ws.rs.core.Response api to build and send back response to front end from my spring boot backend. I have a controller as follows.
#GetMapping(value = "/details")
public Response getDetails() throws ServiceException {
try {
//logic to get details
return Response.status(Response.Status.OK).entity(details).build();
} catch (Exception e) {
log.error(e.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage).build();
}
}
But I am getting 200 OK as the response status for the HTTP Request in the browser/postman even in the case of exceptions. Because of this, the ajax success block executes instead of the error block when there is an exception. Is there any way to make the error block execute in this case? I don't want to throw an exception as it sends the entire stack trace in the response.
#GetMapping is from spring mvc and spring-mvc is not JAX-RS compliant. So don't mix to use them together. Either use pure spring-mvc or pure JAX-RS . you can try to return a spring-mvc ResponseEntity (equivalent to JAX-RS Response) instead:
#GetMapping(value = "/details")
public ResponseEntity getDetails() throws ServiceException {
try {
//logic to get details
return ResponseEntity.ok(details);
} catch (Exception e) {
log.error(e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage);
}
}
I have below code use to POST JSON object to the following URL
HttpEntity messageEntity = new HttpEntity(message, buildHttpHeaders(getTerminalId()));
String theUrl = "http://123.433.234.12/receive";
try {
System.out.println("In try block");
ResponseEntity<Dto> responseEntity= restTemplate.exchange(theUrl, HttpMethod.POST, messageEntity, Dto.class);
} catch (HttpStatusCodeException ex) {
// get http status code
}
If the URL is invalid or service unavailable, I want it throw error status code like 404 or 503. Unfortunatelly it will always stop at the try block..Is there a way to solve that ?
Output
In try block
Edit
String theUrl = "http://123.433.234.12/receive" + transactionId; //invalid Id
try {
System.out.println("=========start=========");
ResponseEntity<Dto> responseEntity= restTemplate.exchange(theUrl, HttpMethod.POST, messageEntity, Dto.class);
System.out.println("=========end=========");
} catch (HttpStatusCodeException ex) {
String a = ex.getStatusCode().toString();
System.out.println(a);
}
Output
=========start=========
2017-09-22 14:54:54 [xles-server-ThreadPool.PooledThread-0-running] ERROR c.r.abc.jpos.JposRequestListener - Error HttpStatusCode 500org.springframework.web.client.HttpServerErrorException: 500 null
It stop and not display ========end ======== or any status code in catch block
Valid url
http://abc0/receive/hello
If I change to
http://abc0/recei/hello
I will get 404 in catch block, it look fine. But when I change to another url that not exits,example
http://123.433.234.12/receive
it is in try block .Why ????
With reference to this doc, you should catch RestClientException instead of just HttpStatusCodeException.
If you want to throw exception in specific scenarios you can do it like this
try {
restTemplate.exchange(...);
}
catch (RestClientException e) {
// implies error is related to i/o.
if (e instanceof ResourceAccessException) {
// java.net.ConnectException will be wrapped in e with message "Connection timed out".
if (e.contains(ConnectException.class)) {
// handle connection timeout excp
}
} else if (e instanceof HttpClientErrorException) {
// Handle all HTTP 4xx error codes here;
} else if (e instanceof HttpServerErrorException) {
// Handle all HTTP 5xx error codes here
}
}
for HttpClientErrorException you can get error code from excption as shown below
HttpClientErrorException clientExcp = (HttpClientErrorException) e;
HttpStatus statusCode = clientExcp.getStatusCode();
like wise, you could get error code for HttpServerErrorException.
As far as I remember RestTemplate.exchange method throws RestClientException. You have HttpStatusCodeException in your catch clause, which is only one of RestClientException subclasses.
The address you're trying to reach (http://123.433.234.12/receive) is not valid address, therefore you can't get ANY response from it (no 200s but no 500s or 400s too). Try to catch RestClientException and print its message to see what is going on. Then you can write some code to manage such situations.
Moreover if that does not work, try to go step by step and check wether ResponseEntity is null and what it has in its body. That's what I'm doing when I try to understand some method ;=)
I'm using ResteasyClient to make a REST client to my another service A. Say, service A throws an exception CustomException with a message : Got Invalid request.
Here is how I am using the Client:
public Response callServiceA(final String query) {
ResteasyClient client = new ResteasyClientBuilder().build();
String link = "abc.com/serviceA";
ResteasyWebTarget target = client.target(link).path("call");
Form form = new Form();
form.param("query", query);
Response response;
try {
String data =
target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(form,
MediaType.APPLICATION_FORM_URLENCODED_TYPE),
String.class);
response = Response.ok().entity(data).build();
} catch (Exception e) {
String message = e.getMessage();
e.printStackTrace();
response = Response.serverError().entity(e.getMessage()).build();
} finally{
client.close();
}
return response;
}
However, when I print the stacktrace, I'm unable to find my custom error message. I can just see the message as HTTP 400 Bad Request.
Could you please suggest me how to access the error message?
NOTE: I am able to get the error message when I call the serviceA using the restClient. Hence, I dont think there is an issue with the service.
Don't deserialize the response straight to a String.
String data = ...
.post(Entity.entity(form,
MediaType.APPLICATION_FORM_URLENCODED_TYPE),
String.class);
When you do this (and there is a problem), you just get a client side exception, which doesn't carry information about the response. Instead just get the Response with the overloaded post method
Response response = ...
.post(Entity.entity(form,
MediaType.APPLICATION_FORM_URLENCODED_TYPE));
Then you can get details from the Response, like the status and such. You can get the body with response.readEntity(String.class). This way you don't need to handle any exceptions. Just handle conditions based on the status.
Do note though that the Response above is an inbound Response, which is different from the outbound Response in your current code. So just make sure not to try and send out an inbound Response.
Also see this answer and it's comments for some design ideas.