---
title: View and Ajax
---
#Sharing objects with view
To register objects to be accessed by view, we use the `include` method:
~~~
#!java
@Controller
class ClientsController {
@Inject
private Result result;
public void search(int id) {
result.include("message", "Some message");
result.include("client", new Client(id));
}
}
~~~
Now the variables `message` and `client` are available to use in your template engine.
It's possible to register the object by invoking the `include` method with only one argument:
~~~
#!java
@Controller
class ClientsController {
@Inject
private Result result;
public void search(int id) {
result.include("Some message").include(new Client(id));
}
}
~~~
In this case, the first invocation registers the `string` key and the second registers the `client` key. You can change this behavior writing your own `TypeNameExtractor`.
##Custom PathResolver
By default, to render your views, VRaptor uses the convention:
~~~
#!java
public class ClientsController {
public void list() {
//...
}
}
~~~
The method above will render the view `/WEB-INF/jsp/clients/list.jsp`. However, if you want to change this behavior for some reason, or if you want to use another template engine like Freemarker or Velocity, you just need to extend the `DefaultPathResolver` class.
~~~
#!java
@Specializes
public class FreemarkerPathResolver extends DefaultPathResolver {
protected String getPrefix() {
return "/WEB-INF/freemarker/";
}
protected String getExtension() {
return "ftl";
}
}
~~~
Thus the logic will render the view `/WEB-INF/freemarker/clients/list.ftl`. If you want more customization, you can implement the `PathResolver` interface. Remember that you need to annotate your implementation with `@Specializes` annotation.
##View
If you want to change the view of some logic, you can use the `Result` object:
~~~
#!java
@Controller
public class ClientsController {
@Inject
private Result result;
public void list() {}
public void save(Client client) {
//...
result.use(Results.logic()).redirectTo(ClientsController.class).list();
}
}
~~~
There are these kinds of implemented views:
| Results.logic() | will redirect to another logic method.
| Results.page() | will redirect directly to one page, may be a JSP, HTML, or any URI on web application dir, or application context.
| Results.http() | send informations of HTTP protocol with status code and headers.
| Results.status() | send status code with more informations.
| Results.referer() | use the header Referer to do redirects or forwards.
| Results.nothing() | just returns the success code (HTTP 200 OK).
| Results.xml() | serializes objects to XML.
| Results.json() | serializes objects to JSON.
| Results.representation() | serializes objects on a format determined by request (_format parameter or header Accept).
{: .content-table}
##Shortcuts on Result
Some redirects are often used, so were created shortcuts for them. The available shortcuts are:
| result.forwardTo("/some/uri") | result.use(page()).forward("/some/uri");
| result.redirectTo("/some/uri") | result.use(page()).redirect("/some/uri)
| result.permanentlyRedirectTo("/some/uri") | result.use(status()).movedPermanentlyTo("/some/uri");
| result.forwardTo(ClientsController.class).list() | result.use(logic()).forwardTo(ClientsController.class).list();
| result.redirectTo(ClientsController.class).list() | result.use(logic()).redirectTo(ClientsController.class).list();
| result.of(ClientsController.class).list() | result.use(page()).of(ClientsController.class).list();
| result.permanentlyRedirectTo(Controller.class) | use(status()).movedPermanentlyTo(Controller.class);
| result.notFound() | use(status()).notFound()
| result.nothing() | use(nothing());
{: .content-table}
Furthermore if the redirect is to another method in the same Controller, we can use:
| result.forwardTo(this).list() | result.use(logic()).forwardTo(this.getClass()).list();
| result.redirectTo(this).list() | result.use(logic()).redirectTo(this.getClass()).list();
| result.of(this).list() | result.use(page()).of(this.getClass()).list();
| result.permanentlyRedirectTo(this) | use(status()).movedPermanentlyTo(this.getClass());
{: .content-table}
##Redirect and forward
With VRaptor we can use both redirect or a forward to another logic or a JSP. Although they are Servlet API concepts, worth remembering the difference: the redirect happens on client side through HTTP codes that will make the browser access a new URL; forward happens on server side, totally transparent for the client/browser.
A good redirect usage example is with 'redirect-after-post' pattern. As example: when you add a client and after the submitted form, the client is returned to the client's listing page. Doing it with redirect, we prevent the user refresh the page (F5) and resubmit all the request, resulting in duplicate data.
In the case of forward, an example of using is when you have a validation and it failed, often you want the user continues on the same screen of form with fulfilled data request, but internally you will make the forward to another business logic (that prepares the necessery data for the form).
##Automatic Flash Scope
If you will add object in the `Result` and do a redirect, these objects will be available in the next request.
~~~
#!java
public void add(Client client) {
dao.add(client);
result.include("message", "Client successfully added");
result.redirectTo(ClientsController.class).list();
}
~~~
list.jsp:
~~~
#!xml
${message}
~~~
##Accepts and the _format parameter
Many times, we need render different formats to the same logic. For example, we want return JSON instead of HTML. To do this, we can define the Header Accepts of request to accept the desired type, or put a `_format` parameter in the request.
If it's a JSON format, the view rendered by default will be: `/WEB-INF/jsp/{controller}/{logic}.json.jsp`, in other words, in general will be render the view: `/WEB-INF/jsp/{controller}/{logic}.{format}.jsp`. If the format is HTML you don't need put it in the filename. The `_format` parameter has priority over the header Accepts.
##Ajax: building in view
To return a JSON in your view, you just need to provide the object to the view, and inside the view you form the JSON as desired.
As example, your `/WEB-INF/jsp/clients/load.json.jsp`:
~~~
#!javascript
{ name: '${client.name}', id: '${client.id}' }
~~~
And the logic:
~~~
#!java
@Controller
public class ClientsController {
@Inject
private Result result;
@Inject
private ClientDao dao;
public void load(Client client) {
result.include("client", dao.load(client));
}
}
~~~
##Ajax: programmatic version
If you want the VRaptor automatically serialize your objects to XML or JSON, you can write in your logic:
~~~
#!java
import static br.com.caelum.vraptor.view.Results.*;
@Controller
public class ClientsController {
@Inject
private Result result;
@Inject
private ClientDao dao;
public void loadJson(Client client) {
result.use(json()).from(client).serialize();
}
public void loadXml(Client client) {
result.use(xml()).from(client).serialize();
}
}
~~~
The results will be simillar to:
~~~
#!javascript
{"client": {
"name": "John"
}}
~~~
and xml:
~~~
#!xml
John
~~~
By default, just primitive types will be serialized (String, numbers, enums, dates), if you want include a field of non-primitive type you need include it explicitly:
~~~
#!java
result.use(json()).from(client).include("address").serialize();
~~~
Will result something like:
~~~
#!javascript
{"client": {
"name": "John",
"address" {
"street": "Vergueiro"
}
}}
~~~
You can also exclude some fields:
~~~
#!java
result.use(json()).from(user).exclude("password").serialize();
~~~
Will result something like:
~~~
#!javascript
{"user": {
"name": "John",
"login": "john"
}}
~~~
You can also exclude or include many fields.
~~~
#!java
result.use(json()).from(user).recursive().serialize(); // includes all fields recursively
result.use(xml()).from(user).exclude("email").serialize(); // exclude the email field
result.use(xml()).from(user).excludeAll().serialize(); // excludes all fields
~~~
You can also add versioning capability to JSON based results.
Through this resource it is possible to add API versioning.
As a useful example, suppose that an API which returns a list of our system's customers was created.
The first version returns a list of customers defined by the structure that follows:
~~~
#!java
public class Customer {
private String name;
private String group;
// getters and setters omitted
}
~~~
Now suppose you've created a controller's method as follows:
~~~
#!java
@Get{"/customers"}
public void customers() {
List customers = customersRepository.getAll();
result.use(json()).from(customers).serialize();
}
~~~
So far, so good. But what if we need to add a new attribute as a result. A new attribute that only makes sense to the new API version.
How could we solve it? We could write a new class named as CustomerV2 with new attribute and rewrite the cotroller's method so it could look like the following code:
~~~
#!java
@Get{"/{versionParameter}/customers"}
public void customers(String versionParameter) {
double version = Double.parseDouble(versionParameter);
if (version == 2.0) {
result.use(json()).from(customersRepository.getAll()).serialize();
} else {
result.use(json()).from(customersRepository.getAllFromV2()).serialize();
}
}
~~~
Certainly, that was not a well suited approach. Regarding that VRaptor comes with GSON lib from Google as a dependency, we can use the same Customer class just by inserting @Since annotation through our new versioned attributes. This annotation, tells that an attribute will be available since an specified version as follows at our new Customer class:
~~~
#!java
public class Customer {
private String name;
private String group;
@Since(2.0)
private Calendar registerDate;
// getters and setters omitted
}
~~~
Now, the our method could be rewritten as follows:
~~~
#!java
@Get{"/{versionParameter}/customers"}
public void customers(String versionParameter) {
double version = Double.parseDouble(versionParameter);
List customers = customersRepository.getAll();
result.use(json()).version(version).from(customers).serialize();
}
~~~
That's all. Now our API clients could request for a specified versioned result.
The default XML Serialization implementation is based on XStream, then you can configure serialization by annotations or direct settings to XStream, just create the class:
~~~
#!java
@Specializes
public class CustomXStreamBuilder extends XStreamBuilderImpl {
@Override
protected XStream xmlInstance() {
XStream xStream = super.xmlInstance();
//your settings to XStream here
return xStream;
}
}
~~~
To configure the JSON serialization you can create a class that extends `GsonJSONSerialization` and overwrite the method `getSerializer()`.
When serialiazing to JSON you can use the annotation `SkipSerialization` to omit the serialization of a field or class.
The following class was annotated with `SkipSerialization`, thus it's fields will never be serialized to JSON:
~~~
#!java
@SkipSerialization
public class UserPrivateInfo {
private String document;
private String phone;
private String address;
// getters and setters
}
~~~
In this another class, the field password will not be serialized. The info field will not be serialized either due to the `UserPrivateInfo` class was annotated with `SkipSerialization`
:
~~~
#!java
public class User {
private String name;
private String login;
@SkipSerialization
private String password;
private UserPrivateInfo info;
// getters and setters
}
~~~
Making the following call:
~~~
#!java
User user = ...;
result.use(json()).withoutRoot().from(user).recursive().serialize();
~~~
The obtained result is similar to:
~~~
#!javascript
{
"name": "John Smith",
"login": "john"
}
~~~
Note that the password field and the entire `UserPrivateInfo` wasn't serialized.
##Serializing Collections##
When serializing collections, by default is put the tag `list` around elements:
~~~
#!java
List clients = ...;
result.use(json()).from(clients).serialize();
//or
result.use(xml()).from(clients).serialize();
~~~
Will result something like:
~~~
#!javascript
{"list": [
{ "name": "John" },
{ "name": "Mary" }
]}
~~~
or
~~~
#!xml
John
Mary
~~~
You can customize the outside element, using the method:
~~~
#!java
List clients = ...;
result.use(json()).from(clients, "clients").serialize();
//ou
result.use(xml()).from(clients, "clients").serialize();
~~~
Will result something like:
~~~
#!javascript
{"clients": [
{"name": "John"},
{"name": "Mary"}
]}
~~~
or
~~~
#!xml
John
Mary
~~~
The includes and excludes work as if you were applied in the element within the list. For example if you want include the address on the client:
~~~
#!java
List clients = ...;
result.use(json()).from(clients).include("address").serialize();
~~~
With result:
~~~
#!javascript
{"list": [
{
"name": "John",
"address": { "street": "Vergueiro, 3185" }
},
{
"name": "Mary",
"address": { "street": "Vergueiro, 3185" }
}
]}
~~~
##JSON serialization without root element
If you want serialize an object in JSON format without naming it, you can do this with the method `withoutRoot`:
~~~
#!java
result.use(json()).from(car).serialize();
~~~
Will result something like:
~~~
#!javascript
{
'car':
{
'color': 'blue'
}
}
~~~
and
~~~
#!java
result.use(json()).withoutRoot().from(car).serialize();
~~~
Will result something like:
~~~
#!javascript
{
'color': 'blue'
}
~~~
##JSON and XML result indentation
By default, the serialization result is without indentation, that is useful to improve browser downloading time.
~~~
#!java
result.use(json()).indented().from(car).serialize();
~~~
Will result something like:
~~~
#!javascript
{
'car':
{
'color': 'blue'
}
}
~~~
Or you can also use the Environment to define the default indentation according with enviroment. In this case you can define that in `DEVELOPMENT` enviroment the indentation will be enabled, and in `PRODUCTION` enviroment will be disabled.
`development.properties`:
~~~
#!properties
br.com.caelum.vraptor.serialization.xml.indented=true
br.com.caelum.vraptor.serialization.json.indented=true
~~~
`production.properties`:
~~~
#!properties
br.com.caelum.vraptor.serialization.xml.indented=false
br.com.caelum.vraptor.serialization.json.indented=false
~~~
**Note:** The `Enviroment` settings has lower priority than code. In other words, if you define `br.com.caelum.vraptor.serialization.xml.indented=false` on `Enviroment` and call the `indented` method in your code, the result will be an indented JSON or XML.
## Creating links on view with linkTo
LinkTo is a functionality that allows you create links on JSP pages without writing link, but just indicating the class of controller, and the method.
To the following controller:
~~~
#!java
public class ClientController {
@Path("/client/list")
public void list() {
// some logic here
}
@Path("/client/{id}")
public void show(Long id) {
// some logic here
}
}
~~~
To call the `list` and `show` methods respectively, we would have to write the JSP:
~~~
#!jsp
list clients
show client 1
~~~
Using the linkTo functionality, we can simplify the call to the `list` method:
~~~
#!jsp
list clients
~~~
Because the method have no parameters, you also can omit the parentheses.
~~~
#!jsp
list clients
~~~
To call the `show` method, we can do a call like this:
~~~
#!jsp
show client 1
~~~
Instead of the fixed parameter, you can pass JSTL variables, for example:
~~~
#!jsp
show client ${client.name}
~~~
##Automatic parameters inclusion
If you annotate your method with `@IncludeParameters`, all method parameters will be automatically included in the view.
So, instead of doing something like:
~~~
#!java
public void filters(Interval interval, Representative representative,
Unit unit, BigDecimal maxValue, BigDecimal minValue) {
// filter logic
result.include("interval", interval);
result.include("representative", representative);
result.include("maxValue", maxValue);
result.include("minValue", minValue);
}
~~~
Now you can do:
~~~
#!java
@IncludeParameters
public void filters(Interval interval, Representative representative,
Unit unit, BigDecimal maxValue, BigDecimal minValue) {
// filter logic
}
~~~
All the parameters will be available by JSP with EL: `${interval.begin}`