Hi I have a simple Rest service:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Product createProduct(Product product) {
if (!(productDao.findByName(product.getProductName()).isEmpty())) {
//?????
} else {
productDao.create(product);
//?????
}
return product;
}
When input name is incorrect and method findByName return not null I want return from my rest service method to angular only information, example "Product exist". When method findByName return null and product is created I want return Product from my method to Angular controller. How handle it? Return entity and information?
And what I handle it in my angular controller? Below controller wokrs good when I return entity, but I don't now why handle information "Product exist" not entity?
$scope.addProduct = function (product) {
$http.post(serviceURI + "products", product).success(function (data) {
$scope.products.push(data);
$('.success-message').fadeIn(1000).delay(5000).fadeOut(1000);
$scope.message = "Product added";
}).error(function (error) {
$('.error-message').fadeIn(1000).delay(5000).fadeOut(1000);
$scope.message = "Error";
});
}
How is the best practice to return data and information from JAX-RS and get it in Angular controller?
Since RESTFul webservices work with the HTTP vocabulary I suggest to return different HTTP status codes depending on the outcome of your operations.
In the first case you could throw a WebApplicationException with a status code of the 4xx family.
In the second case you could use the default status code (I think it would be 200 in this case) or provide a more specific status code such as 201 (Created) by returning a Response object instead of a Product directly.
Eg. Response.created might help you.
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
In my case, I use JAX-RS for the input and Gson for the output when the response is ok because I need to manipulate dates (long/Calendar) and with Gson is easy to add adapters. When the response is not ok, I return a status error code.
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Product createProduct(Product product) {
try {
Gson gson = new GsonBuilder()
//.registerTypeAdapter(Calendar.class, new CalendarSerializer())
// .registerTypeAdapter(Calendar.class, new CalendarDeserializer())
// .registerTypeAdapter(GregorianCalendar.class,
// new CalendarSerializer())
.create();
String json = null;
//do something
json = gson.toJson(product);
return Response.ok(json, MediaType.APPLICATION_JSON).build();
}catch (IllegalArgumentException ex){
return Response.serverError().status(Status.BAD_REQUEST).build();
}catch (Exception ex) {
return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
}
finally{
}
}
Client with AngularJs:
.success (function(data) {
//ok -> get data
})
.error (function(resp) {
if (resp.errorCode == 400){
...
}
...
...
}
Related
I am using angular 8 at front end and java spring boot at back end while running the application I am getting this error. I am new to angular and I guess the error is because of response body from back end but I couldn't solve it.
I have tried the other answers but nothing seems to work.
auth.service.ts
// Method from server should return QueryResultsModel(items: any[], totalsCount: number)
// items => filtered/sorted result
findUsers(queryParams: QueryParamsModel): Observable<QueryResultsModel> {
const httpHeaders = new HttpHeaders();
httpHeaders.set('Content-Type', 'application/json');
return this.http.post<QueryResultsModel>(API_USERS_URL + '/use' + '/findUsers', queryParams, { headers: httpHeaders});
}
Web service java spring boot
// Get All User
#PostMapping(value = "/user/use/findUsers")
public ResponseEntity<List<User>> getAllUserFind() {
try {
return new ResponseEntity<>((List<User>)userService.getAllUser(), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
You need to find out the exact cause of error by gracefully catching the error in your observable resolution. Use
return this.http.post<QueryResultsModel>(API_USERS_URL + '/use' + '/findUsers', queryParams, { headers: httpHeaders})
.pipe(catchError(error)=>{
console.log(error);
return of(null);
});
This will print out the exact error on your console. Remember to import Rx Operators.
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';
Metronic theme ?
It's an amazing Template.
QueryResultsModel is a Model
// fields
items: any[]; <---- This is where you should iterate
importedCount?: number;
activeCount?: number;
totalCount: number;
errorMessage: string;
Good Luck !
So I have a Spring RestController and one of my endpoints is used to perform operations on a generic typed object passed into my RequestBody as so:
#PostMapping("/endpoint")
public <T extends Comparable<T>> ResponseEntity<Integer> balancingPost(#RequestBody MyCustomObject<T> mco)
So after a lot of searching it doesn't seem this can be done without explicitly stating the type at some point. However as it stands my controller has no way of knowing the type (the program calling the POST does though). So how should I handle this? Is there a way to post my Class of T as well and somehow map it?
Try following
public ResponseEntity<?> balancingPost(#RequestBody MyCustomObject<T> mco) {
ResponseEntity<?> response = null;
try {
/*Some condition*/
if (!auth.equals(authCode)) {
response = new ResponseEntity<>("Unauthorized", HttpStatus.UNAUTHORIZED);
} else {
MyModel model = service.getModel();
response = new ResponseEntity<>(model, HttpStatus.OK);
}
} catch (Exception ex) {
response = new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
ex.printStackTrace();
}
return response;
}
I am little confused to decide which way is better that, in jersey we can return Response object(jax-rs) and also customized pojo class object.I dont know which way is better and why.can anybody suggest? Please note the return types in both the cases.Here are my two cases.
case 1:
#POST
#Path("/authentication")
public AuthenticationResponse authenticate(#NotNull FITransXTRequest objFITransXTRequest) {
logger.debug("## entering authenticate method");
System.out.println(objFITransXTRequest);
AuthenticationResponse objAuthResponse = new AuthenticationResponse();
JsonObject objResult = objAuthentication.authenticate(objFITransXTRequest);
System.out.println(objFITransXTRequest);
if (objResult != null) {
objAuthResponse.setStan(objResult.get("stan").getAsString());
objAuthResponse.setErrorMessage(objResult.get("responseMsg").getAsString());
objAuthResponse.setStatus(objResult.get("responseCode").getAsString());
objAuthResponse.setUidNumber(objResult.get("uidNumber").getAsString());
objAuthResponse.setRrn(objResult.get("rrn").getAsString());
objAuthResponse.setRdt(objFITransXTRequest.getDt());
}
return objAuthResponse;
}
case 2:
#POST
#Path("/authentication")
public Response authenticate(FITransXTRequest objFITransXTRequest) {
AuthenticationResponse objAuthResponse = new AuthenticationResponse();
JsonObject objResult = objAuthentication.authenticate(objFITransXTRequest);
System.out.println(objFITransXTRequest);
if (objResult != null) {
objAuthResponse.setStan(objResult.get("stan").getAsString());
objAuthResponse.setErrorMessage(objResult.get("responseMsg").getAsString());
objAuthResponse.setStatus(objResult.get("responseCode").getAsString());
objAuthResponse.setUidNumber(objResult.get("uidNumber").getAsString());
objAuthResponse.setRrn(objResult.get("rrn").getAsString());
objAuthResponse.setRdt(objFITransXTRequest.getDt());
}
return Response.ok( objAuthentication.authenticate(objFITransXTRequest)).build();
}
Note: I want to return only one status code that is 200 ok.
I'm handling an exception in my project
This is my GET endpoint:
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<V6SubnetRec> get(#RequestBody V6SubnetRequest requestBody) throws QIPException {
Site site = getSite(requestBody.getOrganization());
V6SubnetRec wsSubnet = (V6SubnetRec) requestBody.getV6Subnet();
V6SubnetRec v6SubnetRec = null;
try {
v6SubnetRec = getQipService1().getV6Subnets(wsSubnet, site);
} catch (Exception e) {
log.error(Keys.QIP_CALLOUT_ERROR, e);
throw new RestException(e);
}
return new ResponseEntity<V6SubnetRec>(v6SubnetRec, HttpStatus.OK);
}
#ExceptionHandler(RestException.class)
public ResponseEntity rulesForRestException(RestException restEx){
return new ResponseEntity(restEx.getResponse().getContent(), restEx.getResponse().getStatus());
}
RestException.java
#XmlRootElement(name = "RestException")
#XmlAccessorType(XmlAccessType.FIELD)
public class RestException extends RuntimeException{
#XmlElement
RestResponse response;
public RestException(Exception e){
//...
}
}
When I request with URL http://localhost/api/v1/v6subnet.json (return with JSON format), it will return HTTP status code 404 and include the content. It's OK.
But when I request with URL http://localhost/api/v1/v6subnet.xml (return with XML format) with the same request, it return HTTP status code 500 like a normal exception which is not handled as JSON format
I want to have results like when I request to JSON format.
Thanks.
I've fixed my issue. It's only change from
restEx.getResponse().getContent()
into
restEx.getResponse().getContent().toString()
I'm trying to have a #RestController which takes a #PathVariable return a specific object in JSON format, along with proper status code. So far the way the code is, it will return the object in JSON format because it is using Spring 4 built in Jackson library by default.
However I do not know how to make it so it will give a message to the user saying we want an api variable, then JSON data, then Error code (Or success code depending if all went well). Example output would be:
Please enter api value as parameter (NOTE this can be in JSON as well if needed)
{"id": 2, "api": "3000105000" ... } (NOTE this will be the JSON response object)
Status Code 400 (OR proper status code)
The url with parameter look like this
http://localhost:8080/gotech/api/v1/api/3000105000
The code I have so far:
#RestController
#RequestMapping(value = "/api/v1")
public class ClientFetchWellDataController {
#Autowired
private OngardWellService ongardWellService;
#RequestMapping(value = "/wells/{apiValue}", method = RequestMethod.GET)
#ResponseBody
public OngardWell fetchWellData(#PathVariable String apiValue){
try{
OngardWell ongardWell = new OngardWell();
ongardWell = ongardWellService.fetchOneByApi(apiValue);
return ongardWell;
}catch(Exception ex){
String errorMessage;
errorMessage = ex + " <== error";
return null;
}
}
}
A #RestController is not appropriate for this. If you need to return different types of responses, use a ResponseEntity<?> where you can explicitly set the status code.
The body of the ResponseEntity will be handled the same way as the return value of any #ResponseBody annotated method.
#RequestMapping(value = "/wells/{apiValue}", method = RequestMethod.GET)
public ResponseEntity<?> fetchWellData(#PathVariable String apiValue){
try{
OngardWell ongardWell = new OngardWell();
ongardWell = ongardWellService.fetchOneByApi(apiValue);
return new ResponseEntity<>(ongardWell, HttpStatus.OK);
}catch(Exception ex){
String errorMessage;
errorMessage = ex + " <== error";
return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
}
}
Note that you don't need #ResponseBody on a #RequestMapping method within a #RestController annotated class.
The idiomatic way would be to use an exception handler instead of catching the exception in your regular request handling method. The type of exception determines the response code. (403 for security error, 500 for unexpected platform exceptions, whatever you like)
#ExceptionHandler(MyApplicationException.class)
#ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleAppException(MyApplicationException ex) {
return ex.getMessage();
}
#ExceptionHandler(Exception.class)
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleAppException(Exception ex) {
return ex.getMessage();
}