HttpHeaders and status value - spring

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().

Related

How to redirect from spring ajax controller?

I have a controller with #ResponseBody annotation. What I want to do is if this user doesn't exists process user's Id and return a json object. If exists redirect to user page with userInfo. Below code gives ajax error. Is there any way to redirect to user page with userInfo?
#RequestMapping(value = "/user/userInfo", method = {RequestMethod.GET})
#ResponseBody
public String getUserInfo(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) {
if(...){
.....//ajax return
}else{
modelMap.addAttribute("userInfo", userInfoFromDB);
return "user/user.jsp";
}
}
Well, this method is annotated with #ResponseBody. That means that the String return value will be the body of the response. So here you are just returning "user/user.jsp" to caller.
As you have full access to the response, you can always explicitely do a redirect with response.sendRedirect(...);. It is even possible to explicitely ask Spring to pass userInfoFromDB as a RedirectAttribute through the flash. You can see more details on that in this other answer from me (this latter is for an interceptor, but can be used the same from a controller). You would have to return null to tell spring that the controller code have fully processed the response. Here it will be:
...
}else{
Map<String, Object> flash = RequestContextUtils.getOutputFlashMap(request);
flash.put("userInfo", userInfoFromDB);
response.redirect(request.getContextPath() + "/user/user.jsp");
return null;
}
...
The problem is that the client side expects a string response that will not arrive and must be prepared to that. If it is not, you will get an error client side. The alternative would then be not to redirect but pass a special string containing the next URL:
...
}else{
Map<String, Object> flash = RequestContextUtils.getOutputFlashMap(request);
flash.put("userInfo", userInfoFromDB); // prepare the redirect attribute
return "SPECIAL_STRING_FOR_REDIRECT:" + request.getContextPath() + "/user/user.jsp");
}
and let the javascript client code to process that response and ask for the next page.

SOAP UI response

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.

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
}

spring social facebook accessToken with 400 error

Hi please help am new to spring social,i am getting the 400 error while getting the access token from the AUTHORIZATION_CODE..
my code is as follows
#RequestMapping(value = "/facebook", method = RequestMethod.POST, produces = "application/json")
#ResponseBody
public Object getFacebookLoginPage(#RequestBody SocialCommand socialCommand) throws Exception {
loggerService.debug("In ShareController", "getFacebookLoginPage method for facebook", "returns the JSON response for the input socialCommand");
Result result = new Result();
result.status = "OK";
dataObject = socialCommand;
FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory(msgprop.getProperty("facebook.appId"), msgprop.getProperty("facebook.appSecrete"), msgprop.getProperty("facebook.namespace"));
oAuth2Operations = connectionFactory.getOAuthOperations();
OAuth2Parameters params = new OAuth2Parameters();
params.setScope(msgprop.getProperty("facebook.scope"));
params.setRedirectUri(msgprop.getProperty("facebook.redirectURI"));
// params.set("Content-Type", MediaType.MULTIPART_FORM_DATA.getType());
String authorizeUrl = oAuth2Operations.buildAuthorizeUrl(GrantType.AUTHORIZATION_CODE, params);
System.out.println(authorizeUrl);
SuccessResponse successResponse = new SuccessResponse();
successResponse.resultObj = authorizeUrl;
result.response = successResponse;
return result;
}
and the callback controller is as follows
#RequestMapping(value = "/facebook/callback", params = "code", method = RequestMethod.GET)
public Object faceBookCallback(#RequestParam(value = "code") String callBackCode, Model model) throws IOException {
loggerService.debug("In ShareController", "faceBookCallback method for facebook", "returns the JSON response for the input socialCommand");
MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
formData.add("client_id", msgprop.getProperty("facebook.appId"));
formData.add("client_secret", msgprop.getProperty("facebook.appSecrete"));
formData.add("scope", msgprop.getProperty("facebook.scope"));
formData.add("redirect_uri", msgprop.getProperty("facebook.redirectURI"));
formData.set("grant_type", "authorization_code");
formData.set("Content-Type", MediaType.MULTIPART_FORM_DATA.getType());
AccessGrant accessGrant = oAuth2Operations.exchangeForAccess(callBackCode, msgprop.getProperty("facebook.redirectURI"), formData);
System.out.println(accessGrant.getAccessToken());
appStatus.getActivityId();
SocialCommand socialCommand = (SocialCommand) dataObject;
socialCommand.setAppType("facebook");
socialCommand.setAccessToken(accessGrant.getAccessToken());
getImageLocation(socialCommand);
model.addAttribute("activityId", appStatus.getActivityId());
return "backToViewDetails";
}
oAuth2Operations.exchangeForAccess giving the 400 bad request
A couple of things I notice...
First, why are you writing your own controller for performing the OAuth dance instead of using ConnectController that Spring Social provides? ConnectController can handle all of the redirects for you and has been part of Spring Social from the beginning. Spring Social Showcase (https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase) is an example of a project that uses ConnectController.
Even so, assuming you have good reason for writing your own connection controller, I see nothing in getFacebookLoginPage() that performs the actual redirect to Facebook, so I can only assume that happens in code not shown. Then when the redirect comes back from Facebook, I'm puzzled as to why you set the content type and most of those parameters before calling exchangeForAccess(). (Even then, you're setting what looks like a request header, but you're setting it as a form parameter...not necessary, but also not what you had in mind.)
Again, I encourage you to take a look at ConnectController (https://github.com/spring-projects/spring-social/blob/master/spring-social-web/src/main/java/org/springframework/social/connect/web/ConnectController.java). It will probably do what you need it to do. And even if you still feel the need to writing your own controller, you can look at how ConnectController works as a guide to how to write your own controller.

Spring 3 RESTful return on POST (create)

I am new to RESTful services and their implementation on Spring 3. I would like your opinion on the best practices for returning type when a client creates a new resource in my server.
#RequestMapping(method = RequestMethod.POST,
value = "/organisation",
headers = "content-type=application/xml")
#ResponseStatus(HttpStatus.CREATED)
public ??? createOrganisation(#RequestBody String xml)
{
StreamSource source = new StreamSource(new StringReader(xml));
Organisation organisation = (Organisation) castorMarshaller.unmarshal(source);
// save
return ???;
}
A simple choice would be javax.ws.rs.core.Response, found in the Java EE's own restful services package. It - simply - tells what the web server should answer to the HTTP request.
For instance:
if (organisation != null)
return Response.ok().build();
else
return Response.serverError().build();
Custom response headers and other exotic things like that are possible with that return type too, but I don't think that would match with "best practices".
uh, I missed that #ResponseStatus(HttpStatus.CREATED)... I guess my answer was not much of help.
Maybe this will help instead: How to return generated ID in RESTful POST?
I would go for a ResponseEntity<byte[]> and you would have take care of the marshalling of your response on your controller method. Notice that you are basically scrapping the V in MVC, there is a MarshallingView on Spring but from experience I consider the previous solution much more flexible and easier to understand.
It is a good idea to return the newly created entity(with the generated id) wrapped in ResponseEntity. You can also set the HttpStatus in ResponseEntity based on the result of the operation.
#RequestMapping(method = RequestMethod.POST,
value = "/organization",
headers = "content-type=application/xml")
public ResponseEntity<Organization> createOrganisation(#RequestBody String xml) {
StreamSource source = new StreamSource(new StringReader(xml));
Organization organisation = (Organization) castorMarshaller.unmarshal(source);
// save
return new ResponseEntity<Organization>(organization, HttpStatus.OK);
}

Resources