I have this Controller
#Controller
#RequestMapping(value = "/v1.0/user")
public class UserController {
#RequestMapping(value = "/findOne/{id}", method = RequestMethod.GET)
public #ResponseBody String findOne(#PathVariable("id") Integer id) {
log.info("findOne");
return "found URL";
}
}
Which will match the URL: http://localhost:8080/v1.0/user/findOne/4
But if my path varibale is not correct: http://localhost:8080/v1.0/user/findOne/4A
The I get nothing. Not even an error. It's as if Spring swallowed the URL.
I added
#RequestMapping(value = "/.*", method = RequestMethod.GET)
public #ResponseBody String redirectEverythingOtherThanTest(){
log.info("no url matched");
return "badly formed URL for Users";
}
Again I get nothing. What I'm trying to accomplish is for each Controller to have a unique message when the URL does not match.
In the end in each of my Controller classes I added
#ExceptionHandler(Exception.class)
public #ResponseBody String handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return e.getMessage();
}
And this will catch all exceptions and I can treat it as a catch all.
Related
Is it possible to return html web page as very long string from Spring endpoint? For example:
#PostMapping(value = "/redirect/{token}", consumes = { MediaType.APPLICATION_XML_VALUE,
MediaType.APPLICATION_JSON_VALUE },
MediaType.APPLICATION_JSON_VALUE })
public ModelAndView handleRedirectMessage(#PathVariable("token") String token,
#RequestBody PaymentTransaction transaction, HttpServletRequest request) throws Exception {
String body = "<html>.....</html>";
return new ModelAndView("redirect:" + body);
}
I would like to return html page body when user opens the Spring end point into the web browser.
As suggested by #user2478398
#PostMapping(value = "/redirect/{token}",produces = MediaType.TEXT_HTML_VALUE)
public String handleRedirectMessage(#PathVariable("token") String token,
#RequestBody PaymentTransaction transaction, HttpServletRequest request) throws Exception {
String body = "<http>.....</html>";
return body;
}
Try to use produce as - produces = MediaType.TEXT_HTML_VALUE
I have changed your code and you can changed it your way , this is an idea to resolved you problem
#PostMapping(value = "/redirect/{token}",produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView handleRedirectMessage(#PathVariable("token") String token,
#RequestBody PaymentTransaction transaction, HttpServletRequest request) throws Exception {
String body = "<HTML><body>Now you can redirect just do it man !!.</body></HTML>";
return new ModelAndView("redirect:" + body);
}
I wrote a REST Call which will return health status when called
#RestController
#RequestMapping(value = "/account")
public class HealthCheckController {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
#RequestMapping(value = "/health", method = RequestMethod.GET, produces = { "application/json" })
#ResponseStatus(HttpStatus.OK)
#ApiOperation(value = "Returns the health status of the application", notes = "Load balancer user this to confirm the health of the node")
public #ResponseBody String getHealth(HttpServletRequest request, HttpServletResponse response) throws Exception {
log.info("***" + RequestCorrelation.getId() + "***" + "HealthCheckController - getHealth () Called");
return "{\"health\":{\"SERVICES\":\"OK\"}}";
}
}
When I open this in swagger or postman it returns proper response. But when i hit this URL in chrome browser i am seeing
This page contains the following errors:
error on line 1 at column 1: Document is empty
Below is a rendering of the page up to the first error.
Why so? and how to fix this?
Having the same issue. Have an object with the following class annotations and method:
#Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#GET
#Path("version")
public String getVersion() { return "v1"; }
Added MediaType.TEXT_PLAIN to the end of the #Produces annotation. Didn't work.
Moved it the beginning of the #Produces annotation. Didn't work.
Moving/Adding it to the method resolved the issue for me. Your client will need to be able to accept that media type as well.
#GET
#Path("version")
#Produces({MediaType.TEXT_PLAIN})
public String getVersion() { return "v1"; )
HTH
In your getHealth() method, you're returning a String but in your #RequestMapping annotation, you specify that your method will produce JSON.
Try one of these:
#RequestMapping(value = "/health", method = RequestMethod.GET, produces = { "text/plain" })
//Now, pass Accept = "text/plain" in the request header:
or
#RequestMapping(method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public List<String> getHealth(..) {
/*
...
*/
ArrayList<String> list=new ArrayList();
list.add("Health OK");
return list;
}
This would give you
["Health OK"] in the response.
Try to return not a String but
return new ResponseEntity<>(yourString, HttpStatus.OK);
and also change this
public #ResponseBody String getHealth(HttpServletRequest request, HttpServletResponse response) throws Exception {
to this
public #ResponseBody ResponseEntity<String> getHealth(HttpServletRequest request, HttpServletResponse response) throws Exception {
And if it doesn't work, try to add .xml or .json to the end of your URL, when you accessing it in browser.
I'm trying to catch an error scenario but I'm getting an exception in all cases.
Below is my code snippet:
#RequestMapping(value = "/config/file/data", method = RequestMethod.GET)
#ResponseBody
#ExceptionHandler(RestClientException.class)
#ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Not Found")
public void restClientException()
{
//do nothing
}
public List<myfile> getAllmyfiles() throws RestClientException
{
return myfileService.getAllmyfiles();
}
try this :
#ExceptionHandler(RestClientException.class)
#ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Not Found")
public void restClientException()
{
//do nothing
}
#RequestMapping(value = "/config/file/data", method = RequestMethod.GET)
#ResponseBody
public List<myfile> getAllmyfiles() throws RestClientException
{
return myfileService.getAllmyfiles();
}
you shouldn't use a #RequestMapping with an #ExceptionHandler : the method annotated with #ExceptionHandler is automatically invoked when the specified exception is thrown
I am working to pass data from one controller to another.
I have one class that is annotated with #ControllerAdvice that is used to handle all exception of application.
I am processing exception and adding them to custom class then in ModelAndView I am adding that and passing to another controller using redirect.
And in that controller I want that added object but I don't have much idea about it how to get that object. I have tried some trick but did not get success.
Code:
ExceptionHandler class:
#ControllerAdvice
public class DefaultExceptionHandler {
#Autowired
private CPro cPro;
private static final Logger LOG = LoggerFactory.getLogger(DefaultExceptionHandler.class);
#RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
#ExceptionHandler(Exception.class)
#ResponseStatus(value = INTERNAL_SERVER_ERROR)
#ResponseBody
public ModelAndView handleException(Exception ex) {
ModelAndView modelAndView = new ModelAndView("redirect:/");
String exceptionType = ex.getClass().getSimpleName();
DefaultExceptionHandler.LOG.error("Internal Server Exception", ex);
ErrorResponse response = new ErrorResponse();
if (ex.getCause() != null) {
response.addSimpleError(exceptionType, ex.getCause().getMessage(), cPro.getProName());
} else {
response.addSimpleError(exceptionType, ex.getMessage(), cPro.getProName());
}
modelAndView.addObject("processingException", response);
return modelAndView;
}
}
my home controller:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String getHomePage(#ModelAttribute("processingException") ErrorResponse errorResponse, Model model) {
// I want to get object data of processingException added in exception handler using ModelAndView
model.addAttribute("processingException", errorResponse.getError() == null ? null : errorResponse);
return "upscale"; //here upscale.html redirection
}
Does anyone have idea that how to get that object data in my controller ?
Thanks.
After a lot googling and searching various forums and article, I found some solution. I have combined data and code of various forums I have made my requirement fulfill.
We can use FlashMap for that. Just get context of request and add FlashMap and add other data to FlashMap as well.
Code:
#ControllerAdvice
public class DefaultExceptionHandler {
#Autowired
private CPro cPro;
private static final Logger LOG = LoggerFactory.getLogger(DefaultExceptionHandler.class);
#ExceptionHandler(Exception.class)
public String handleException(Exception ex, HttpServletRequest request) throws IOException {
DefaultExceptionHandler.LOG.error("Internal Server Exception", ex);
String exceptionType = ex.getClass().getSimpleName();
ErrorResponse response = new ErrorResponse();
if (ex.getCause() != null) {
response.addError(exceptionType, ex.getCause().getMessage(), cPro.getProName());
} else {
response.addError(exceptionType, ex.getMessage(), cPro.getProName());
}
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
if (outputFlashMap != null) {
outputFlashMap.put("processingException", response);
}
return "redirect:/";
}
}
and other hand, in controller use ModelAttribute to get data that is sent from exception handler method.
code:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String getHomePage(Model model, #ModelAttribute("processingException") Object processingException) {
if (processingException instanceof ErrorResponse) {
model.addAttribute("processingException", ((ErrorResponse) processingException).getError());
} else {
model.addAttribute("processingException", null);
}
return "upscale"; //here upscale.html redirection
}
After all bingo.. Done my work.
If anyone have still better idea on it then still welcome..
Thanks guys.
You could make a workaround like this:
public ModelAndView handleException(Exception ex, HttpServletRequest req) {
//...
ModelAndView modelAndView = new ModelAndView("forward:/");
//...
req.setAttribute("processingException", response);
Then in your Controller Method you have access to HttpServletRequest and get the Attribute (Object):
public String getHomePage(#ModelAttribute("processingException", HttpServletRequest req)
{
//....
req.getAttribute("processingException");
Using Spring REST API [Spring MVC]
Scenario:
when request comes to the EmployeeController , it is forced to forward the request/response to another URI,if it falls under a specific logic.
The controller method has RequestMapping set with 'RequestMethod.POST' and the destination controller- SpecialController has the method named invalidRequest() that has RequestMapping set with 'RequestMethod.GET'
EmployeeController:
#RestController
#RequestMapping(value = "/employee")
public class EmployeeController {
String res = null;
#RequestMapping(value = "/update", method = RequestMethod.POST)
public String updateEmployeeDetails(HttpServletRequest httpRequest, HttpServletResponse httpResponse,
#Valid #RequestBody Employee emp) throws ServletException, IOException {
// based on logic, forward the request to a different controller that handles invalid request
if( ...) { // condition checking
RequestDispatcher requestDispatcher = httpRequest.getServletContext().getRequestDispatcher("/invalidRequest");
requestDispatcher.forward(httpRequest, httpResponse);
}
if(..someother condition..) {
String res = "something";
}
return res;
Destination Controller:
#RestController
#RequestMapping(value = "/invalidRequest")
public class SpecialController {
#RequestMapping(value = "", method = RequestMethod.GET)
public String invalidRequest(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
httpResponse.setStatus(401);
return "invalidRequest";
}
}
Question: Inconsistency Problem [Actual Problem]:
In 90% of the times, this is working, but a few times very rarely, I get the below error.
If I am getting this error always, then it would have made some meaning and I would have the below mentioned 'possible fix'
But since it is working most of the times, and not working only sometimes, I need your help in finding out why?
> org.springframework.web.HttpRequestMethodNotSupportedException:
> Request method 'POST' not supported
> at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:198)
> at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:286)
> at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:233)
> at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:56)
> at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:300)
> at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1101)
> at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:916)
> at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
> at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
> at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
possible fix if the error was consistent:
#RestController
#RequestMapping(value = "/invalidRequest")
public class SpecialController {
#RequestMapping(value = "", method = RequestMethod.GET)
public String invalidRequest(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
httpResponse.setStatus(401);
return "invalidRequest";
}
#RequestMapping(value = "", method = RequestMethod.POST)
public String invalidRequest2(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
return invalidRequest(httpRequest, httpResponse);
}
}