RESTful error response Spring instead of tomcat page - java

I want to return a custom JSON as response body in case of errors. I tried doing this for 404 error code. I created a controller which looks like this.
#RequestMapping("/**")
#Controller
public class IOTExceptionController {
public void handleInvalidURL() throws ResourceNotFoundException {
throw new ResourceNotFoundException("Requested resource does not exist."
+ " Please check the URL.");
}
}
And the ControllerAdvice class I've setup will return the response as JSON.
So whatever URL which will not be found in other controllers will be handled here and 404 error is returned.
Unfortunately, the Tomcat error page for 404 is all I'm getting. Can anyone please let me know whether there is any flaw in this logic/code?

Related

Redirect to external URL from request mapping method in spring

Below is the request mapping method:
#GetMapping("/redirect")
public ResponseEntity<Void> redirect() {
String url = "http://yahoo.com";
return ResponseEntity.status(HttpStatus.FOUND)
.location(URI.create(url))
.build();
}
When I hit the URL http://somehost:8080/redirect in the browser I see that it takes me to yahoo.com, but when the /redirect is called from the UI(reactjs) the 302 Found httpstatus value is returned in the browser console but the page on the browser is blank. I was expecting to see the yahoo.com page. Seems it is not redirecting.
I referred this link: Redirect to an external URL from controller action in Spring MVC
reactjs code:
yield globalAxios.get(http://somehost:8080/redirect)
Below image when the http://somehost:8080/redirect gets called from the UI
Below image is when we the /redirect redirects to the link: yahoo.com
Is it because of the 405 method not allowed error as seen in the above image
Just in case if someone run into something like this in the future.
I end up using this code getting rid of 405 method not allowed while I am doing PUT-REDIRECT-GET pattern.
Notice it is #Controller and not #RestContorller. Otherwise it won't work.
If this is to be implemented in an existing rest controller you may want to add #ResponseBody over the other methods but not on these.
#Controller
#RequestMapping("/redirect")
public class RedirectController {
#PutMapping()
public String redirect() {
return "redirect:/redirect";
}
#GetMapping()
public String redirectPost() {
return "redirect:https://www.google.com";
}
}

Getting 500 undocumented error as "Connection prematurely closed DURING response" after executing rest api for file upload

Created a rest api in Springboot application which takes file through POST rest api and do some processing and returns some response.
but when executed that post api it shows an error below as..
Connection prematurely closed during response
Code snippet for the restcontroller is as follows.
#CrossOrigin(origins="*")
#RestController
#RequestMapping("/")
public class Script{
#Autowired
ScriptService sevice;
private static final Logger logger = (Logger) LoggerFactory.getLogger(LensMigration.class);
#PostMapping("/api/v1/execute/script")
public ResponseEntity<Map<String, Integer>> executeScript(#RequestParam(value = "file") MultipartFile file)
throws IOException {
logger.info("inside endpoint!!!");
if (file.isEmpty()) {
throw new FileNotFoundException("file doen not exists!!");
} else {
BufferedReader csvReader = new BufferedReader(new InputStreamReader(file.getInputStream()));
return new ResponseEntity<>(service.migrateOldRecords(csvReader), HttpStatus.OK);
}
}
}
I have used some loggers at start of controller to check if it is executing, but didn't get any logs printed.
May be error due to response time
so I have tried to increase the response time using servlet property but it didn't worked
server.connection-timeout=60000
could anyone help me here please.
Actually it is very strange to me that it gets solved by just adding the #RequestMapping annotation to different path.
The root cause of the issue was the endpoint inside controller was not visible. The actual error I was expecting is that 404 not found for this particular POST api.
I did get 404 not found error for another GET endpoint which I just written below this POST api.
So due to this 404 I was looking for visibility of the endpoint
and its gets resolved.

Spring Boot - Is it possible to return a File OR xml from web service depending on success?

I've been tasked to create a web service that fetches a file from an Azure storage account.
On sucess: return the file as the payload
On error: return an xml response.
The xml response will contain a copy of the request, error codes and messages etc as the user will need a helpful error message explaining what happened.
I can find instructions for how to return a single object/media type, but not multiple types dependent on condition.
Is this possible?
Solved with an exception handler thanks to Abhijeet's comment
- important to add the contentType or it returns JSON by default
#ControllerAdvice
public class MyExceptionHandler {
#ResponseStatus(HttpStatus.I_AM_A_TEAPOT)
#ExceptionHandler(MyException.class)
#ResponseBody
ResponseEntity<?> exceptionHandler(MyException e){
InvoiceArchiveResponse responseObject = e.getResponseObject();
return ResponseEntity.badRequest()
.contentType(MediaType.parseMediaType("application/xml"))
.body(responseObject);
}
}
Thanks!

SpringMVC based Rest Service - StackOverflowError when path is not defined

I'm creating a project using the #RestController annotation of Spring 4. Everything is working fine, when I call a URL path that is configured I receive a well formatted answer or an error if something happened.
But, if I call a service in a path that is not defined, I'm getting the following exception:
java.lang.StackOverflowError
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:229)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:592)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:229)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:592)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:229)
at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:592)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:229)
I know this error is happening because my request could not be mapped to a resource, but I'm wondering why I am not getting a 404 - Not found error type?
My DispatcherServlet is configured like this:
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
This is a sample of my Service classes:
#RestController
#RequestMapping("/Genotypes")
public class GenotypeService {
... #Autowired objects here ...
#RequestMapping(method=RequestMethod.GET)
public #ResponseBody List<Genotype> findGenotypesLike(#RequestParam(value="genName", required=false) String name, #RequestParam(value="like", defaultValue="false") Boolean like){
if(name == null){
return genotypeBO.findAllGenotypes();
}
return genotypeBO.findByName(name, like);
}
If I call http://localhost:8080/MyApp/Genotypes I get my response but if I call http://localhost:8080/MyApp/SomethingNotMapped the exception is thrown and the error code at the browser side is a 500 - Internal Server Error
By the way, my application is running on Apache Tomcat v7.0.
Thanks in advance for any suggestion.

Tomcat 7 default bad request page conflict #ControllerAdvice

I am currently developing a webservice which will always return json as a response to any request(all good request are working already). I would like to return a json when the http status of the request is a bad request(status 400 to be exact). I used the #ControllerAdvice of spring mvc to do the job:
#ControllerAdvice
public class RestErrorHandler {
#ExceptionHandler(Exception.class)
#ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Something went wrong. Please check your JSON REQUEST!")
public #ResponseBody ErrorClass processValidationError() {
// some stuff in setting the error response
return new ErrorClass();
}
But what happen is that it returns the default Tomcat 7 error message for bad request and not the json I set. processValidationError() will return an ErrorClass instance which will automatically be in json format using jackson plugin. Did I missed something?

Categories