I want to use something similar to HttpServletRequest.getPathInfo(); which returns the entire path of request. This is used in java, I am trying to find something similar in Grails.
Thanks.
The request object is an instance of the Servlet API's HttpServletRequest interface.
You should try that in your controller : (in order to show the entire path of the request in the webpage)
def index = { render request.forwardURI }
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.
This sounds like a simple enough question, but can't find the answer for the life of me. How does one convert a root-relative url (~/my/path) to a virtual path (/mywebsite/my/path) in the Controller and/or Model?
On a view it's easy enough to do, just call #Url.Content("~/my/path/"). And getting the physical path in the controller is just as easy using Server.MapPath("~/my/path"). But I can't figure out how to get the virtual path in the controller.
My main issue is that I have a root-relative path of an image that I will be passing to a JSON object that will be returned. In most cases this will be read by javascript and put on the page somewhere, and I can't use #Url.Content in my javascript code. Also, in some instances this JSON object will be used by an external application that won't understand what the ~ means.
In the controller you could use the Url property:
public ActionResult Foo()
{
string url = Url.Content("~/my/path");
...
}
In the Model you don't do anything like this. A model shouldn't know anything about url generation. It simply not its responsibility. If it needs to work with an url this url should be passed to it by the layers of your application that deal with urls (which are the layers that have access to an HttpContext).
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.
Is there possible get request type in controller? How?
To detect if the request is a master or not requires the use of the RequestStack, which should be injected into your controller. The request stack has 3 useful methods
getCurrentRequest();
getMasterRequest();
getParentRequest();
The getParentRequest() will always return null if the current request is the master.
I was looking for this myself, and it seems it is just passed around, so there doesn't seem to be one single place that knows what it is.
My thought for solving this would be to create a simple kernel.request listener that just adds an attribute to the request. Rough (un-tested) code below:
public function onKernelRequest(GetResponseEvent $event)
{
$event->getRequest()->attributes->set('_request_type', $event->getRequestType());
}
Then in the controller you should be able to do:
$requestType = $this->getRequest()->attributes->get('_request_type');
Again this is untested. You would need to write out the full listener class and add it to the services config file, but other than that I think this will work.
Easy, just call the getMethod() method on your Request object:
$method = $this->get('request')->getMethod();
This will return the HTTP method of the current request, e.g. GET, POST, PUT or DELETE.
Flex3 + Cairngorm. I have my service in Servicis.mxml:
<mx:HTTPService id="docIndex" url="{URL_PREFIX}/jobs/{???}/docs" resultFormat="e4x"/>
And I call it from my generic restful delegate like this:
public function index(params:Object):void {
var call:AsyncToken = services.getHTTPService(resourceName+"Index").send(params);
call.addResponder(responder);
}
I want to know how I can use the params Object I pass inside the url definition (the ??? above). And please tell me how you would go about searching an answer to this in the documentation, I'd like to be a little more independet on these problems...
EDIT: I'll explain myself if you didn't understand my problem:
I have a restful api written in rails to which I'm connecting. Doc is a child resource of Job. If I want to get all docs I have to supply a job_id too. Therefore in the service the url must be changed for each .send() call, with the proper job_id (the ??? part above). I'd like to call it like myDelegate.index({job_id:34}) and insert that job_id field in the Service URL.
Write a class that extends HTTPService and allows you to set parameters into the url. Then, in your index function you can fetch it with services.getHTTPService, and call a function you create that sets the url values for you.
In your service locator create an instance of your class rather than a flat HTTPService.