SOAP UI response - spring

I want to view the response for the below method in SOAP UI. The url would be as below to call the accountDetails(..) method in SOAP UI to check the response.
http://localhost:8080/AccountInfo/rest/account/0003942390
#RequestMapping(value = /accountDetails/{accNum}, method = RequestMethod.GET)
public void accountDetails(#PathVariable final String accNum)
{
final boolean accountValue = service.isAccountExists(accNum);
if (!accountValue )
{
throw new Exception();
}
}
The method is executed correctly but the response i'm getting in SOAP UI is 404.
accountDetails(..) method return type is void, so do i need to set any extra parameters when i have to check the response for the method in SOAP UI with void return type to show success message.
Below is the message shown in SOAP UI:
HTTP/1.1 404 /AccountInfo/WEB-INF/jsp/account/0003942390/accountInfo.jsp
Server: Apache-Coyote/1.1

Is the exception thrown? If yes, how does the framework handle the exception?
Your method doesn't return anything - see here. Based on the RESTful nature of the URL it seems the method should return something like an AccountDetail. However, if you really just want to see the 200 then just return something like a non-null String.

Related

HttpHeaders and status value

I have a spring boot application. I use a rest architecture.
I have this method.
#RequestMapping(value = "/members/card/{cardId}", method = RequestMethod.HEAD)
public ResponseEntity hasCardIdValid(#PathVariable(value = "cardId") String cardId) {
return memberService.hasCardIdValid(cardId) ? new ResponseEntity(HttpStatus.OK) : new ResponseEntity(HttpStatus.NOT_FOUND);
}
I another application, I would like to call hasCardIdValid method.
I wrote this code
HttpHeaders response = restTemplate.headForHeaders("/rest/members/card/{cardId}", cardId);
I don't find a way to get the 200 or 404 value from response. I don't see any method for that.
Is it possible?
This is because you are getting back HttpHeaders as a result of your restTemplate#headForHeaders() method call.
If you want to get hold of the status you'll have to invoke one of the RestTemplate#exchange() methods instead (there are a few overloaded method signatures) that is giving you back a ResponseEntity on which you can invoke getStatus().

Empty request body gives 400 error

My Spring controller method looks something like this:
#RequestMapping(method=RequestMethod.PUT, value="/items/{itemname}")
public ResponseEntity<?> updateItem(#PathVariable String itemname, #RequestBody byte[] data) {
// code that saves item
}
This works fine except when a try to put a zero-length item, then I get an HTTP error: 400 Bad Request. In this case my method is never invoked. I was expecting that the method should be invoked with the "data" parameter set to a zero-length array.
Can I make request mapping work even when Content-Length is 0?
I am using Spring framework version 4.1.5.RELEASE.
Setting a new byte[0] will not send any content on the request body. If you set spring MVC logs to TRACE you should see a message saying Required request body content is missing as a root cause of your 400 Bad Request
To support your case you should make your #RequestBody optional
#RequestMapping(method=RequestMethod.PUT, value="/items/{itemname}")
public ResponseEntity<?> updateItem(#PathVariable String itemname, #RequestBody(required = false) byte[] data) {
// code that saves item
}

Switching ASP.Net Web API returns between XML and JSON; where's it done?

I have an ASP.Net Web API project. In my controller is this simple 'boiler plate' API method:
using System.Web.Http;
public class DataController : ApiController
{
private static Random _Random = new Random();
[Route("api/getrandomdoubles/{count:int}")]
[AcceptVerbs("GET", "POST")]
public double[] GetRandomDoubles(int count)
{
var doubles = new double[count];
for (var i = 0; i < count; i++)
{
doubles[i] = _Random.NextDouble();
}
return doubles;
}
}
(N.B. I've cut out the other methods.)
If I call this in the browser thus http://localhost:1165/api/GetRandomDoubles/2 I get XML returned:
<ArrayOfdouble xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<double>0.3777879822895806</double>
<double>0.46401416811347668</double>
</ArrayOfdouble>
And if I call it from JavaScript thus:
d3.json('api/getrandomdoubles/2', function (error, data) {
//Do stuff
});
I get back JSON [0.6679551008473873,0.9205140638726363].
What is deciding when my controller API method returns XML and when it returns JSON? I'm guessing it is decided based on the HTTP verb, i.e. PUT or GET but I cannot see where that is specified. How would I control the return type myself?
========== EDIT ==========
I have just realised that this is browser specific. Calling http://localhost:1165/api/GetRandomDoubles/2 in IE returns JSON, calling it in Chrome returns XML.
It is called as Content Negotiation in Web API.
First, the pipeline gets the IContentNegotiator service from the HttpConfiguration object. It also gets the list of media formatters from the HttpConfiguration.Formatters collection.
Next, the pipeline calls IContentNegotiatior.Negotiate, passing in:
The type of object to serialize
The collection of media formatters
The HTTP request
The Negotiate method returns two pieces of information:
Which formatter to use
The media type for the response
If no formatter is found, the Negotiate method returns null, and the client recevies HTTP error 406 (Not Acceptable).

Send Status code and message in SpringMVC

I have the following code in my web application:
#ExceptionHandler(InstanceNotFoundException.class)
#ResponseStatus(HttpStatus.NO_CONTENT)
public ModelAndView instanceNotFoundException(InstanceNotFoundException e) {
return returnErrorPage(message, e);
}
Is it possible to also append a status message to the response? I need to add some additional semantics for my errors, like in the case of the snippet I posted I would like to append which class was the element of which the instance was not found.
Is this even possible?
EDIT: I tried this:
#ResponseStatus(value=HttpStatus.NO_CONTENT, reason="My message")
But then when I try to get this message in the client, it's not set.
URL u = new URL ( url);
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
huc.setRequestMethod("GET");
HttpURLConnection.setFollowRedirects(true);
huc.connect();
final int code = huc.getResponseCode();
String message = huc.getResponseMessage();
Turns out I needed to activate custom messages on Tomcat using this parameter:
-Dorg.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER=true
The message can be in the body rather than in header. Similar to a successful method, set the response (text, json, xml..) to be returned, but set the http status to an error value. I have found that to be more useful than the custom message in header. The following example shows the response with a custom header and a message in body. A ModelAndView that take to another page will also be conceptually similar.
#ExceptionHandler(InstanceNotFoundException.class)
public ResponseEntity<String> handle() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("ACustomHttpHeader", "The custom value");
return new ResponseEntity<String>("the error message", responseHeaders, HttpStatus.INTERNAL_SERVER_ERROR);
}

Set HTTP status code for redirect when returning a String in a Spring 3 controller

Is there a way to specify the HTTP status code when returning "redirect:/new/url" in Spring 3?
Haven't tried it, but looking at the source of org.springframework.web.servlet.view.RedirectView it has getHttp11StatusCode() method that determines the HTTP status of response.
It seems like you can override the default response code by settings org.springframework.web.servlet.View#RESPONSE_STATUS_ATTRIBUTE property on request. Simply set:
httpServletRequest.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, status)
before returning with "redirect:" view.
As noted by Scolytus, you must return a RedirectView with the statusCode set. Using the "redirect:" prefix will always result in a status of HttpStatus.MOVED_TERMPORARILY (302).
If you need the ability to return String from your controller method as well as RedirectView, you must change the method signature to return Object. Example:
#RequestMapping
public Object someMethod() {
if (doRedirect) {
RedirectView rv = new RedirectView("/new/url");
rv.setStatusCode(HttpStatus.MOVED_PERMANENTLY); // set our own status code
return rv;
} else {
return "someView";
}
}

Resources