How to get the #RequestBody in an #ExceptionHandler (Spring REST) 2.0 - spring

I know How to get the #RequestBody in an #ExceptionHandler (Spring REST) exists but I am looking for a slightly different solution. When my service gets a 403 it does not make it to my #Controller class. Thus, how can I still grab something out of the incoming request body, since this scenario would never actually hit my code? It only ever hits the generated CGLIB code.

Ultimately I was able to solve the issue by creating a class that extends RequestBodyAdviceAdapter.

Related

Testing ControllerAdvice with AutoConfigureMockMvc and CompletableFuture

I have added a REST controller returning CompletableFutures to a project using a ControllerAdvice to translate exceptions into error DTOs.
My controller doesn’t throw the exceptions, wrapping them into failed CompletableFutures and returning these.
When running the full application and manually testing it works as expected, but in my tests the mockMvc won’t trigger the advices and always return HTTP 2xx.
Any idea why?
If you have a standalone setup of MockMvc, then you need to specify the controller advice to be used (if any) while creating the mockMvc instance as follows:
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(new YourControllerAdvice())
.build();
The reason for this is that you don't have a context here for spring to detect the controller advice.
I figured out my test was not correct (or, to put it another way.. the testing framework is not designed as I expected ;)
When testing controllers returning CompletableFutures one needs to use asyncDyspatch as in
https://github.com/spring-projects/spring-framework/blob/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java

Is there any way to force Spring to check EL expressions on app start?

I have endpoints in #RestControllers that look similar to this:
#RestController
#RequestMapping("/rest/x")
public class XApiController
{
// ...
#PostMapping(...)
#PreAuthorize("#apiAuthService.canAccessX(#headers)")
public void saveX(...)
{
// ...
}
}
These endpoints require the developer to make the HttpHeaders object available and name it correctly in the method declaration:
public void saveX(#RequestHeader HttpHeaders headers)
Our problem is that if this last step isn't done, the endpoint only fails at runtime when the endpoint is invoked. This means that issues from large refactors later (say, to change the HttpHeaders argument to HttpServletRequest) aren't easy to identify. Is there any way to tell Spring to validate these expressions are valid on app startup?
I suggest you to create integration tests and then invoke saveX from the test to verify this before you deploy an application.
I would also state my opinion that if you want to have testable code with good quality - try to get rid of SpringEL as soon as possible. In my experience this approach proved as poorly testable, hardly maintainable and also introducing unnecessary complications to your source code.
In modern spring framework there are lots of ways to avoid writing SpringEl.
Spring always validates all beans on start up. But your problem is not within validation your problem is test problem. The process of pre authorization is a runtime job. Spring can not know what to do with this expression spring just checks its syntax over SPEL rules.
You can create tests to check header.
You can increase your IDE inspection level of spring spel to error.
You can simply write a static method to get the headers without a rest parameter.

Spring MVC interceptor

I need inputs related to Spring MVC, I have a URL to which a client will send a post request with an xml as the pay load. I plan to have a controller method which maps to the requested url, I want that xml to be validated/converted to an object using jaxb before controller method is executed. And also, the controller method should have only the object as the parameter to its methods and no httprequest etc.
So, how do I achieve this? Will interceptor be helpful? If yes, how will it be done?
I plan to use Spring 3.
Simply use #RequestBody in conjunction with #Valid on a method argument and that is all you need.
public void myRequestHandlingMethod(#Valid #RequestBody YourJaxbObject jaxbObject) { … }
I strongly suggest you take a look at the Spring reference guide

Adding headers to Spring controllers

I know this question is very similar to this one, but I feel its different and specific enough to warrant its own question here.
I've just inherited a Java web app project from a sole developer who left no documentation behind. Its a Spring MVC app with a basic package structure as follows:
com.ourOrg.app.controllers
ImageController
ProgramController
UserController
com.ourOrg.app.otherPackages
Each Controller class is just a POJO annotated with #Controller and #RequestMapping("/blah"). For instance:
#Controller
#RequestMapping("/images")
public class ImageController() {
#RequestMapping(value="/saveImage", method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<String> saveImage(#RequestParam(value="imageData", required=true) String imageXML, HttpServletRequest request){
// This method gets executed whenever the:
// http://ourSite.com/images/saveImage
// URL is hit
}
}
I have been asked to add the following HTTP headers to the Spring config so that we disable browser caching:
Pragma: no-cache
Cache-Control: no-cache
Expires: -1
The article I linked to above makes it sound like our controllers should be extending this WebContentGenerator class. Unfortunately, there are dozens of controllers with an enormous number of methods, so refactoring each one to extend or inherit some base type is not really a viable option (unless its the only option!).
I've also seen articles that make it sound like you have to configure Spring to use AOP interceptors that modify your response headers, but now I'm really getting into unfamiliar territory.
Given our setup and implementation of Spring MVC, whats the easiest way for me to add these three simple headers to every response sent back by the server (regardless of which controller or method is executed)?
Thanks in advance!
Hoping you are using Spring 3, you can look at an interceptor, then you won't have to modify all of your controllers (since you said you had many). It looks like they may already have one implemented that you can just use. Check out Bozho's answer to this question how to set header no cache in spring mvc 3 by annotation
I realize this is an old post but maybe this will help somebody. I am using Spring for this example.
The main thing is use the annotation for parameters:
#Controller
public class HelloController {
#RequestMapping(value = "/hello.htm")
public String hello(#RequestHeader(value="User-Agent") String userAgent)
//..
}
}

How do I use HandlerAdapter in the Spring MVC framework to test #ResponseBody controller actions?

I'm currently using Spring MVC's HandlerAdapter to test the annotations of my Spring controller actions to make sure the path variables, request parameters, session attributes, #Valid, etc. are being written correctly.
I've come across a problem where if a controller action has #ResponseBody and doesn't return a ModelAndView, I cannot test the response using the HandlerAdapter.
I found a question on this site that is related, but the accepted answer given is not satisfactory:
How to unit test a ResponseBody or ResponseEntity sent by a spring mvc Controller?
How can I test the annotations and the results at the same time? Or do I need to write two tests - one to test the annotations, and another to call the controller method directly?
Thanks
If you have a #ResponseBody then the handler shouldn't return a ModelAndView, it should write directly to the Response using a MessageConvert.
One approach would be to intercept the Response and read it instead of reading the returned value.
please have a look at this answer I just found to your very same question I had:
I found that very useful and I'm implementing this solution in my test code.

Resources