Struts2 con Anotaciones JSON y Datatables Ejemplo
Este ejemplo usa Struts2 con anotaciones y proporciona la información a datatables a través de JSON.
Caraterísticas
- El Datatables usa JSON.
- El Action se parse actomáticamete por el framework de Struts2.
- Se puede comunicar Struts2 con el datatables a través de una función de callback.
- Se puede ordenar por una columna el resto están deshabilitadas.
1 - Descargar el War
2 - Despliega el war
Una vez que hayas desplegado el war en tu servidor. (En tomcat arranca el contenedor web y mueve el war al directorio webapps)
- http://localhost:8080/TestJSONStruts/test URL principal.
- http://localhost:8080/TestJSONStruts/json/testJSON para testear que funciona el JSON.
- Usa FireBug similar para comprobar el JSON
TestJsonAction
package com.mdtel.autonoma.tribulete.action.json; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; @ParentPackage("json-default") public class TestJSONAction extends ActionSupport{ private static final long serialVersionUID = 634243322166735407L; private List<TestView> data = new ArrayList<TestView>(); private Integer draw=0, recordsTotal=1, recordsFiltered = 0, length = 0, start=0; private String error_custom; private static final Logger logger = Logger.getLogger(TestJSONAction.class); @Action(value="testJSON", results = { @Result(name="success", type="json") }) public String execute() { recordsTotal = 100; recordsFiltered = recordsTotal; logger.info("New JSON request"); //print all parameters from the action context Map<String, Object> map = ActionContext.getContext().getParameters(); for (Map.Entry<String, Object> entry : map.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); System.out.println("key:"+ key +" value: " + Arrays.toString((String[])value)); } //gets the order from the datatable String order = ""; if(map.get("order[0][dir]")!=null){ order = ((String[]) map.get("order[0][dir]"))[0]; } //The arrayList will be turned into data = new ArrayList<TestView>(); //creates a mock DAO int auxStart = 0, accu =1; if(order.indexOf("asc")>-1){ auxStart = start; } else { auxStart = recordsTotal-start; accu=-1; } for(int i = 0; i<length; i++){ TestView rv = new TestView(); rv.setName("Juan" + auxStart); rv.setSurname("Surname" + auxStart); rv.setAmount(10000+auxStart); rv.setId(auxStart); auxStart+=accu; data.add(rv); } //sends an random error to the JSON if((Math.random()*10>9)){ error_custom = "Random Error test"; } return SUCCESS; } public List<TestView> getData() { return data; } public void setData(List<TestView> data) { this.data = data; } public class TestView { private int id; private String name=""; private String surname=""; private Integer amount=0; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public Integer getAmount() { return amount; } public void setAmount(Integer amount) { this.amount = amount; } } public Integer getDraw() { return draw; } public void setDraw(Integer draw) { this.draw = draw; } public Integer getRecordsTotal() { return recordsTotal; } public void setRecordsTotal(Integer recordsTotal) { this.recordsTotal = recordsTotal; } public Integer getRecordsFiltered() { return recordsFiltered; } public void setRecordsFiltered(Integer recordsFiltered) { this.recordsFiltered = recordsFiltered; } public Integer getLength() { return length; } public void setLength(Integer length) { this.length = length; } public Integer getStart() { return start; } public void setStart(Integer start) { this.start = start; } public String getError_custom() { return error_custom; } public void setError_custom(String error_custom) { this.error_custom = error_custom; } }
TestAction
package com.mdtel.autonoma.tribulete.action; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Actions; import org.apache.struts2.convention.annotation.Result; import com.opensymphony.xwork2.ActionSupport; public class TestAction extends ActionSupport{ private static final long serialVersionUID = 9086900467866735407L; @Actions({ @Action(value = "/", results = @Result(name = "success", location = "/test.jsp")), @Action(value = "/test", results = @Result(name = "success", location = "/test.jsp")) }) public String execute() { return SUCCESS; } }
Test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Test</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script src="js/jquery-1.11.1.min.js" type="text/javascript"></script> <script src="js/jquery-ui.min.js" type="text/javascript"></script> <link href="addons/datatables/media/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css" /> <script src="addons/datatables/media/js/jquery.dataTables.min.js" type="text/javascript"></script> <link href="addons/datatables/TableTools/css/dataTables.tableTools.min.css" rel="stylesheet" type="text/css" /> <script src="addons/datatables/TableTools/js/dataTables.tableTools.js" type="text/javascript"></script> </head> <body> <p> <s:text name="com.welcome"/> </p> <table id="tablaprincipal" class="display" style="color: black;font-size: .8em;padding-left: 4px;table-layout: fixed;word-wrap: break-word;"> <thead> <tr> <th>Id </th> <th>Name </th> <th>Surname</th> <th>Salary</th> </tr> </thead> </table> <script> function handleData( responseData ) { var value = responseData.json['error_custom']; if(value!=null){ alert(value); } } $(document).ready(function() { /* Datatables with fullnumbers, no bFilter(Search Field) * only the first column is orderable */ $('#tablaprincipal').dataTable( { "processing": true, "serverSide": true, "ajax": "json/testJSON", "columnDefs": [ { orderable: false, targets: [1,2,3] }], "sPaginationType": "full_numbers", "bFilter": false, "columns": [ { "data": "id" }, { "data": "name" }, { "data": "surname" }, { "data": "amount" } ], "fnDrawCallback" : function(data) { handleData(data); } } ); } ); </script> </body> </html>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.action.extension" value="" /> <constant name="struts.custom.i18n.resources" value="global" /> <constant name="struts.devMode" value="false" /> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.convention.default.parent.package" value="default" /> <constant name="struts.ognl.allowStaticMethodAccess" value="true" /> <constant name="struts.action.excludePattern" value="/do/.*,/addons/.*?,/dt/.*?,.*?.jsp,.*?.png,.*?.css,.*?.js,.*?.gif,.*?.jpeg,.*?.jpg,.*?.ico,.*?.html" /> <constant name="struts.multipart.maxSize" value="50000000" /> <package name="default" extends="struts-default"> </package> </struts>
Notas
- Probado con Apache Tomcat 1.6 y 1.7
- El archivo de logs de log4j está apuntando al directorio de los del tomcat log4j.appender.file.File=${catalina.base}/logs/Vivait-Tracker.log
- Versión Struts2 es la 2.3.14, el JSON plug ya está el WEB-INF/libs