--- 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 ~~~ 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}`