Now I'm working on a spring web-flow unit test. I have to retrieve "HttpServletRequest" from MockExternalContext. But MockExternalContext don't support providing HttpServletRequest.How can I do to solve this problem
MockHttpServletRequest is not a wrapper around HttpServletRequest, but rather its substitution for unit tests without servlet container. It can give you everything HttpServletRequest gives. Can you describe why do you need HttpServletRequest?
Related
We plan to use content type negitiation as a form of versioning for our rest API but it seems more complex than it should be.
Given the follwing example code :
#RestController
#RequestMapping("/products")
ProductController {
.......
#RequestMapping(value = "/{productID}", method = RequestMethod.GET, produces = "productVersion2/json")
public ResponseEntity<ProductV2> getVersion2(#PathVariable String productID) {
.......
return new ResponseEntity<ProductV2>(product, HttpStatus.OK);
The correct method is being called when test this from e.g postman, but i get a HTTP 406 Not Acceptable as a response. I have been looking several places, but I have not found a a page with a good explanation of what i need to do to make this work.
The response is to be parsed with json just like all other requests, but the response object is modified.
The thought is that we by doing this can support several "versions" of the same API and we can gradually make clients move over to the new api, while still having the same uri/resource to access.
Can anyone point to a good tutirial or a step by step guide of how this can be solved in spring boot ?
I have read this article : http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc/#combined-controller
but I was not able to get a clear anderstanding of what was needed to make it work
Your media type is wrong. To use custom media types for API versioning you could use application/productVersion2+json instead of productVersion2/json. I suspect you get the 406 because Spring Boot has no way to find out how to serialize your object into JSON because productVersion2/json isn't a valid media type for json data.
There is more than one way to pick a media type to do this, I've googled a more comprehensive document here.
I am working on struts 2.0 . I am designing a web application.
I am using Jasper Report in my application. I want to access the *.jrxml files in my action class. I don't want to give hard coded path to the files. So to get the path dynamically I googled it and got the solution that I can get the path using getRealPath() method. But I found two implementation of doing this:
Using HttpSession to get object of ServletContext and using the getRealPath() method of the ServletContext object.
Like this:
HttpSession session = request.getSession();
String realPath = session.getServletContext().getRealPath("/");
The second approach to do it directly using the static method getServletContext() of ServletActionContext. And then we can get the real path of the application using the getRealPath() method.
Like this:
String realPath = ServletActionContext.getServletContext().getRealPath("/");
Please tell me, is there any difference between the above two and also please tell me whether there is any other way to get the path?
Neither is "better", really, and I'd argue that neither is particularly good, either.
I might try getting the context path in an initialization servlet and stick it into the application context, then make your action(s) ApplicationAware and retrieve the value from the map.
This has the added benefit of aiding testability and removing the static references in the action.
That said, I see zero reason to go through the extra mechanics of your first approach: it adds a lot of noise for no perceivable benefit; I'm not even sure why it wuld be considered.
I'd also be a little wary of tying your actions to a path like this unless there's a real need, what's the specific use? In general you shouldn't need to access intra-app resources by their path.
I have the following code in my controller action method:
if (User.Identity.IsAuthenticated)
{
// ...
}
It seems to work fine. But when I run a unit test that calls this action, it fails because User is null?
Can anyone suggest the best way to deal with this? Do I have to restructure this code just for unit tests?
You probably need to set the User property as part of your setup. You would do this by mocking the HttpContextBase via ControllerContext used to create the controller so that it returns your mocked user. Set your mocked ControllerContext into the ControllerContext property, and it will find User provided you've configured the object graph correctly.
The User property of the Controller class is copied from the current HttpContext - you have to provide a context and set the User there appropriately for this to work in your unit tests.
User will be null if you run the code outside of the context of a web request. It sounds like you're running tests on your methods directly.
You have two options.
The quickest fix to your problem, but not necessarily the most sustainable fix, would be to simply call your running website from your unit test as a WebRequest.
The more sustainable fix would be to gather your uses of context-dependent server-side functionality (such as User) into a single class that you can mock/fake.
Edit
Can anyone suggest the best way to deal with this? Do I have to restructure this code just for unit tests?
The bottom line answer is "yes". More importantly, you probably want to, because it will make your system more flexible and/or maintainable in the long run.
I'm rephrasing my existing question to a more generic one. I want to know if Velocity has got implicit object references like JSP does.
I'm particularly interested in knowing about the request object.
In JSP we can get the attribute in the request scope like <%= request.getAttribute("req1") %>
I know that JSP is a servlet and <%= request.getAttribute("req1") %> ends up as a part of _jspService() method which has the request object available to it before the scope of the request ends.
I'm not sure how Velocity works behind the scenes (it may be leaving the request object behind by the time it plays it role)
To test that I did the following thing which was a the part of my previous question.
I have a Spring MVC TestController in which I'm setting a request attribute. I'm using Velocity templates for rendering the views.
#RequestMapping(value="/test", method=RequestMethod.GET)
public ModelAndView display(HttpServletRequest req, HttpServletResponse resp){
...
req.setAttribute("req1", "This should be present for first request");
...
}
In the Velocity template I'm doing something like
Request: $request.getAttribute('req1')
but I'm not getting the value of req1. I know I should have put req1 in model map instead of request but I want to know about implicit request object ref.
I tried $req1 as well but its not working.
When I'm doing the same thing with the model and returning it back, everything is working correctly.
Where am I going wrong?
Update: The same thing is happening with req.getSession().setAttribute("req1", testObject) also.
Salaam,
req.getSession().getAttribute("req1", testObject) == $req1
AFAIK, you cannot access the request object at VelocityViewServlet's templates, unless you explicity set the request object in context or use a v-tool .
Take a look at this question: Velocity + Spring. The Spring folks haven't kept the integration with Velocity very up to date.
Once you've created that extension and set it up to be used properly in your servlet configuration, you'd be able to simply put the object on the ModelAndView and from there do whatever you need with it.
Can anyone describe when and why you might want to use Spring MVC ModelAndView instead of just returning a String for the view name and using a ModelMap.
I know one method is older than the other, but I don't know why one method might be better than the other?
Thanks
I think other than one style being newer than the other there is no one better way.
The String view name + ModelMap is probably more familiar to developers coming from Struts though.
One more advantage of using ModelAndView is that it tell's the Spring container explicitly that you want to send a View and not a string in case if you are using #ResponseBody in your controller say for AJAX calls, this way if there is an error in your jsp, with ModelAndView you will get an exception whereas in the String version the String will be returned as it is to the view page without throwing any exception......