Quite often your business logic may finish with two (or more) different results.
How do you select which view page should be used in each different result?
In the following examples, we use component and business logic named catalog and import.
By default, VRaptor allows your method to use void as it's return type: it goes for the page called:
${component}/${logic}.ok.jsp
So in the following example:
package org.vraptor.example.view; @Component public class CatalogLogic { public void import() { // view key is catalog.import } }
The resulting jsp file would be:
catalog/import.ok.jsp
If your method's return type is String, you can give different results. For example:
package org.vraptor.example.view; @Component public class CatalogLogic { public String import() { if(Math.random() > 0.5) { // view key is catalog.import.big return "big"; } else { // view key is catalog.import.small return "small"; } } }
Would go to:
result.equals("big") --> catalog/import.big.jsp result.equals("small") --> catalog/import.small.jsp
Sometimes you might want to change the default file output for a simple result...
Let's say, for example, that you want to go to catalog/too_big.jsp if the result is big.
First create a views.properties file in your classpath. Add the following to your views.properties file:
catalog.import.big = /catalog/too_big.jsp
That's it! If the result is catalog.import.big, this property is looked up in your views file and, if not found, the flow goes to the default file.... as it's not the case, we have overriden the default flow to go to catalog/too_big.jsp.
In order to solve the typical refresh problem, where the user hits refresh and instead of listing all data, he executes the last action before listing, you can simply override the view with the redirect prefix:
catalog.import.big = redirect:catalog/too_big.jsp
This will execute a client side redirect to catalog/too_big.jsp.
There is no slash at the begining as this redirect will be executed on the client side and means something relative to your current webapplication.
Cliente side redirection also supports a simple expression language capable of calling getters on your outjected objects i.e.:
catalog.import.big = redirect:catalog/too_big.jsp?id=${catalog.id}
Sometimes you don't wan't to redirect to any view, i.e. when you use the OutputStream to send a binary download (like a pdf report).
To tell VRaptor that you don't desire any view redirection simply use the @Viewless annotation in your business logic method.
Refer to the file download example to see it working.
The pattern mentioned earlier which goes to jsp files in different directories can be easily changed.
Simply add to your vraptor.xml file the following xml tag:
... <regex-view-manager>/$component/$logic.$result.vm</regex-view-manager> ...
This would go to velocity templates based on velocity tools generic servlet instead of jsp files, for example...