A new feature to include a response within another one. There are many questions on the web and stackoverflow about whether spring mvc supports this and as far as I know there is no default implemantion within the framework.
ASP .NET MVC provides this feature as "Child actions" and Grails also has this feature which we have used in many projects. While this is not a "MVC" related feature, it is especially helpful in MVC environments where a controller action view can include other helper actions. This is different than including partial views such that, this "child action" can implement business rules or can query some database etc. This helps build more reusable sub components while separating controller logic and view logic.
While this is possible by writing a custom tag to coordinate your business logic and separate it from the view logic, including a controller method response is more rapid, easier for the developer and view technology ignorant.
Usage Say for instance a shopping cart summary is displayed on all pages by the "CartController" -> "display" handler method. Then the view developer will use it like this:
<s:include path="${s:mvcUrl('CC#display')}" >
<s:param name='mode' value='summary' />
</s:include>
An example prototype project to show various usage scenarios and capabilities can be found here.
Implementation I grabbed some part from Grails and some from Tomcat's SSI filter implementation.
Current implementation depends on StreamByteBuffer class authored by Graeme Rocher in Grails framework to capture the response in a in-memory buffer.Since this buffer uses chunks, it should be way more performant than a standard ByteArrayOutputStream especially for too many write operations.Graeme uses one byte buffer and one char buffer for write operations but I used byte buffers for both the printwriter and the outputstream.
Included request has its own request params given to the constructor but if requested, it may also fall back to the original request params. Generally, this fallback is not a good choice because decreases reusability but in some cases, you find yourself copying request params from the main request to the child requests. For instance when displaying a product detail page, you may include child actions which all depend on the same product id. One way to do this is to set it as an attribute in the main request and allow child actions to get it. Fallback to main request params solves this issue but maybe an improvement can be to filter these params with a "whitelist" or "blacklist".
Another improvement may be to prevent child actions to respond to direct requests. In ASP .NET MVC you can define "ChildActionOnly" handler methods which can only be used within an include. Grails does not have this feature.
Additionaly in the future, we may put some kind of hierarchical state to the request attributes so that a handler method can check if it is working within a parent handler. This may help deciding on what and how to display based on the hierarchical handler stack. For instance, ASP .NET action exception handler uses this information when rendering exception response.
Although I have some unit tests here, and I created a sample project to see this in action, I could not find a way to write some functional tests.
Example Project Example project on Github
Comment From: pivotal-issuemaster
@ckalan Please sign the Contributor License Agreement!
Click here to manually synchronize the status of this Pull Request.
See the FAQ for frequently asked questions.
Comment From: bclozel
Thank you for the PR! Could you please create an issue for this pull request in the Spring Framework issue tracker. When you do, please make sure to fill the Reference URL
with the link to this PR. Thanks!
Comment From: pivotal-cla
@ckalan Please sign the Contributor License Agreement!
Click here to manually synchronize the status of this Pull Request.
See the FAQ for frequently asked questions.
Comment From: bclozel
Closing as #18832 has been closed.