Struts 2 and JQuery Example project with Jasper for Reporting

In continuation to my last article I will give the code needed for a Struts 2 and JQuery project. I will call the project TransportBooking. The important additions we make to JQuery is Jasper reporting which will add reporting functionality to the results in our grid.

Please note I will try to outline as much of the source code as I can to aid and assist in getting a sample project up and running. I also focus on the lesser known parts like multiple search criteria for JQGrid. I have seen many questions on this on the web.

The outline of the project is:

The classes are as follows:

The EditTransportBookingAction and JsonTableAction use the JQuery plugin to give a web frontend that is searchable and has the ajax effects for the webpage. Hibernate is used as ORM and we use hibernate projections for the queries.

The EditTransportBookingAction.java looks like:

package za.co.transporter.transportbooking.action;

import java.util.Date;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.hibernate.Transaction;

import com.googlecode.s2hibernate.struts2.plugin.annotations.TransactionTarget;

import com.opensymphony.xwork2.ActionSupport;

import za.co.transporter.transportbooking.dao.TransportBookingDao;
import za.co.transporter.transportbooking.model.TransportBooking;

@Results( {
      @Result(name = “error”, location = “messages.jsp”)
    })
public class EditTransportBookingAction extends ActionSupport {

      private static final long serialVersionUID = -3454448309088641394L;
      private static final Log  log              = LogFactory.getLog(EditTransportBookingAction.class);

      private TransportBookingDao      TransportBookingDao     = new TransportBookingDao();
     
      private String            oper             = “edit”;
      private String id;
        private String name;
        private String phone;
        private String cellnumber;
        private Date confirmBy;
        private String transport;
     

      @TransactionTarget
      protected Transaction     hTransaction;

      public String execute() throws Exception
      {
        log.debug(“Edit Customer :” + getId());

        TransportBooking customer;

        try
        {
          if (getOper().equalsIgnoreCase(“add”))
          {
            log.debug(“Add Customer”);
            customer = new TransportBooking();

            int nextid = TransportBookingDao.nextTransportBookingNumber();
            log.debug(“Id for ne Customer is ” + nextid);
            customer.setBookingId(nextid);
            customer.setName(getName());
            customer.setPhone(getPhone());
            customer.setCellnumber(getCellnumber());
            customer.setConfirmBy(getConfirmBy());
            customer.setTransport(getTransport());
           
            TransportBookingDao.save(customer);
          }
          else if (getOper().equalsIgnoreCase(“edit”))
          {
            log.debug(“Edit Customer”);

            customer = TransportBookingDao.get(Integer.parseInt(getId()));
            log.debug(customer.getBookingId());
            customer.setName(getName());
            log.debug(customer.getName());
            customer.setPhone(getPhone());
            log.debug(customer.getPhone());
            customer.setCellnumber(getCellnumber());
            log.debug(customer.getCellnumber());
            customer.setConfirmBy(getConfirmBy());
            log.debug(customer.getConfirmBy());
            customer.setTransport(getTransport());
            log.debug(customer.getTransport());
           
            TransportBookingDao.update(customer);
          }
          else if (getOper().equalsIgnoreCase(“del”))
          {
            StringTokenizer ids = new StringTokenizer(getId(), “,”);
            while (ids.hasMoreTokens())
            {
              int removeId = Integer.parseInt(ids.nextToken());
              log.debug(“Delete Customer ” + removeId);
              TransportBookingDao.delete(removeId);
            }
          }

          // Commit changes
          hTransaction.commit();
        }
        catch (Exception e)
        {
          hTransaction.rollback();
          addActionError(“ERROR : ” + e.getLocalizedMessage());
         
          for(int i=0; i < e.getStackTrace().length && i < 4 ;i++)
              addActionError(“ERROR : ” + e.getStackTrace()[i]);
         
          addActionError(“Is Database in read/write modus?”);
          return “error”;
        }
        return NONE;
      }

    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPhone() {
        return phone;
    }

    public void setCellnumber(String cellnumber) {
        this.cellnumber = cellnumber;
    }

    public String getCellnumber() {
        return cellnumber;
    }

    public void setConfirmBy(Date confirmBy) {
        this.confirmBy = confirmBy;
    }

    public Date getConfirmBy() {
        return confirmBy;
    }

    public void setTransport(String transport) {
        this.transport = transport;
    }

    public String getTransport() {
        return transport;
    }

    public void setOper(String oper) {
        this.oper = oper;
    }

    public String getOper() {
        return oper;
    }

     
    }

The IndexAction.java looks like:

package za.co.transporter.transportbooking.action;

public class IndexAction {

}

The JsonTableAction.java looks like:

package za.co.transporter.transportbooking.action;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.SessionAware;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import za.co.transporter.transportbooking.dao.TransportBookingDao;
import za.co.transporter.transportbooking.model.TransportBooking;

import com.opensymphony.xwork2.ActionSupport;

@Result(type = “json”)
public class JsonTableAction extends ActionSupport implements SessionAware{

  private static final long serialVersionUID = 5078264277068533593L;
  private static final Log  log              = LogFactory.getLog(JsonTableAction.class);

  // Your result List
  private List<TransportBooking>   gridModel;

  // get how many rows we want to have into the grid – rowNum attribute in the
  // grid
  private Integer           rows             = 0;

  // Get the requested page. By default grid sets this to 1.
  private Integer           page             = 0;

  // sorting order – asc or desc
  private String            sord             = “asc”;

  // get index row – i.e. user click to sort.
  private String            sidx;

  // Search Field
  private String            searchField;

  // The Search String
  private String            searchString;

  // he Search Operation
  // [‘eq’,’ne’,’lt’,’le’,’gt’,’ge’,’bw’,’bn’,’in’,’ni’,’ew’,’en’,’cn’,’nc’]
  private String            searchOper;

  // Your Total Pages
  private Integer           total            = 0;

  // All Records
  private Integer           records          = 0;
 
  //Multiple Search
  private String filters;

  private Map session;

  private TransportBookingDao      transportBookingDao     = new TransportBookingDao();

  public String execute()
  {
    log.debug(“Page ” + getPage() + ” Rows ” + getRows() + ” Sorting Order ” + getSord() + ” Index Row :” + getSidx());
    log.debug(“filters :” + filters);

    // Calcalate until rows ware selected
    int to = (rows * page);

    // Calculate the first row to read
    int from = to – rows;

    //JSON Object
    JSONObject jsonFilter = null;
   
    //Multiple search filters
    if(filters != null){
        log.debug(“filters :” + filters);   
        jsonFilter = (JSONObject) JSONSerializer.toJSON( filters );
    }
   
   
    // Criteria to Build SQL
    DetachedCriteria criteria = DetachedCriteria.forClass(TransportBooking.class);

   
    if(jsonFilter != null ){
         String groupOp = jsonFilter.getString(“groupOp”);
         log.debug(“groupOp :” + groupOp);
        
         JSONArray rules = jsonFilter.getJSONArray(“rules”);
         int rulesCount = JSONArray.getDimensions(rules)[0];
         log.debug(“Count Rules :” + rulesCount);
        
         for (int i = 0; i < rulesCount; i++) {
               JSONObject rule = rules.getJSONObject(i);
               log.debug(“field :” + rule.getString(“field”));
               log.debug(“op :” + rule.getString(“op”));
               log.debug(“data :” + rule.getString(“data”));
              
              
                   if (rule.getString(“field”).equals(“bookingId”)){

                       Integer searchValue = Integer.parseInt(rule.getString(“data”));
                       if (rule.getString(“op”).trim().equals(“eq”)) criteria.add(Restrictions.eq(rule.getString(“field”), searchValue));
                       else if (rule.getString(“op”).trim().equals(“ne”)) criteria.add(Restrictions.ne(rule.getString(“field”), searchValue));
                       else if (rule.getString(“op”).trim().equals(“lt”)) criteria.add(Restrictions.lt(rule.getString(“field”), searchValue));
                       else if (rule.getString(“op”).trim().equals(“gt”)) criteria.add(Restrictions.gt(rule.getString(“field”), searchValue));
                       else if (rule.getString(“op”).trim().equals(“ge”)) criteria.add(Restrictions.ge(rule.getString(“field”), searchValue));
                       else if (rule.getString(“op”).trim().equals(“le”)) criteria.add(Restrictions.le(rule.getString(“field”), searchValue));

                   }else if (rule.getString(“field”).equals(“name”) || rule.getString(“field”).equals(“phone”) || rule.getString(“field”).equals(“cellnumber”) || rule.getString(“field”).equals(“confirmBy”) || rule.getString(“field”).equals(“transport”)){

                       if (rule.getString(“op”).trim().equals(“eq”)) criteria.add(Restrictions.eq(rule.getString(“field”), rule.getString(“data”)));
                       else if (rule.getString(“op”).trim().equals(“ne”)) criteria.add(Restrictions.ne(rule.getString(“field”), rule.getString(“data”)));
                       else if (rule.getString(“op”).trim().equals(“lt”)) criteria.add(Restrictions.lt(rule.getString(“field”), rule.getString(“data”) + “%”));
                       else if (rule.getString(“op”).trim().equals(“gt”)) criteria.add(Restrictions.gt(rule.getString(“field”), “%” + rule.getString(“data”) + “%”));
                       else if (rule.getString(“op”).trim().equals(“ge”)) criteria.add(Restrictions.ge(rule.getString(“field”), “%” + rule.getString(“data”) + “%”));
                       else if (rule.getString(“op”).trim().equals(“le”)) criteria.add(Restrictions.le(rule.getString(“field”), “%” + rule.getString(“data”) + “%”));

                   }
              
              
           }
    }

    // Count TransportBooking
    records = transportBookingDao.countByCriteria(criteria);

    // Reset count Projection
    criteria.setProjection(null);
    criteria.setResultTransformer(Criteria.ROOT_ENTITY);

 
    // Get TransportBooking by Criteria
    gridModel = transportBookingDao.findByCriteria(criteria, from, rows);

    // Set to = max rows
    if (to > records) to = records;

    // Calculate total Pages
    total = (int) Math.ceil((double) records / (double) rows);

    if( getSession() != null){
        log.debug(“Session exists”);
       
        if(getSession().get(“reportsList”) != null){
            getSession().remove(“reportsList”);
        }
        getSession().put(“reportsList”, gridModel);
    }else{
        log.debug(“Session does not exist. Creating New Session”);
        setSession(new HashMap<String, Object>());
        getSession().put(“reportsList”, gridModel);
    }
   
    return SUCCESS;
  }

  public String getJSON()
  {
    return execute();
  }

  /**
   * @return how many rows we want to have into the grid
   */
  public Integer getRows()
  {
    return rows;
  }

  /**
   * @param rows
   *          how many rows we want to have into the grid
   */
  public void setRows(Integer rows)
  {
    this.rows = rows;
  }

  /**
   * @return current page of the query
   */
  public Integer getPage()
  {
    return page;
  }

  /**
   * @param page
   *          current page of the query
   */
  public void setPage(Integer page)
  {
    this.page = page;
  }

  /**
   * @return total pages for the query
   */
  public Integer getTotal()
  {
    return total;
  }

  /**
   * @param total
   *          total pages for the query
   */
  public void setTotal(Integer total)
  {
    this.total = total;
  }

  /**
   * @return total number of records for the query. e.g. select count(*) from
   *         table
   */
  public Integer getRecords()
  {
    return records;
  }

  /**
   * @param record
   *          total number of records for the query. e.g. select count(*) from
   *          table
   */
  public void setRecords(Integer records)
  {

    this.records = records;

    if (this.records > 0 && this.rows > 0)
    {
      this.total = (int) Math.ceil((double) this.records / (double) this.rows);
    }
    else
    {
      this.total = 0;
    }
  }

  /**
   * @return an collection that contains the actual data
   */
  public List<TransportBooking> getGridModel()
  {
    return gridModel;
  }

  /**
   * @return sorting order
   */
  public String getSord()
  {
    return sord;
  }

  /**
   * @param sord
   *          sorting order
   */
  public void setSord(String sord)
  {
    this.sord = sord;
  }

  /**
   * @return get index row – i.e. user click to sort.
   */
  public String getSidx()
  {
    return sidx;
  }

  /**
   * @param sidx
   *          get index row – i.e. user click to sort.
   */
  public void setSidx(String sidx)
  {
    this.sidx = sidx;
  }

  public void setSearchField(String searchField)
  {
    this.searchField = searchField;
  }

  public void setSearchString(String searchString)
  {
    this.searchString = searchString;
  }

  public void setSearchOper(String searchOper)
  {
    this.searchOper = searchOper;
  }

  public void setFilters(String filters) {
      this.filters = filters;
  }

  public String getFilters() {
      return filters;
  }

  public void setSession(Map session) {
        this.session = session;
    }

    public Map getSession() {
        return session;
    }
 
 
}

In the above class note that we have are using multiple search criteria in our queries meaning that on the front end we can filter by a group of items at once hence why we have filters and jsonFilter. Also we use hibernate projections to build our query.

Now we look at the JasperCsvAction.java. The is where we use jasper reports to generate our reports. This overcomes the problem that the Struts-JQuery plugin lacks reporting tools.

package za.co.transporter.transportbooking.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.ResultPath;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.views.jasperreports.*;

import net.sf.jasperreports.engine.JasperCompileManager;

import za.co.transporter.transportbooking.model.TransportBooking;

import com.opensymphony.xwork2.ActionSupport;

@Result(name=”success”, type=”jasper”, params={“location”, “/transportbooking_template.jasper”, “dataSource”, “reportsList”, “format”, “CSV”,”documentName”,”transportbooking.csv” })
public class JasperCsvAction extends ActionSupport implements SessionAware{

    /** List to use as our JasperReports dataSource. */
    private List<TransportBooking> reportsList;
  
    private Map session;
   
    private static final Log  log              = LogFactory.getLog(JasperAction.class);
   
    public String execute() throws Exception {

        log.debug(“Creating Reporting”);      
        log.debug(reportsList);
       
        reportsList = (List<TransportBooking>) getSession().get(“reportsList”);
        // Normally we would provide a pre-compiled .jrxml file
        // or check to make sure we don’t compile on every request.
        try {
            JasperCompileManager.compileReportToFile(
                    “F:/programming-tools/apache-tomcat-7.0.2/webapps/web-deploy/transportbooking_template.jrxml”,
                    “F:/programming-tools/apache-tomcat-7.0.2/webapps/web-deploy/transportbooking_template.jasper”);
        } catch (Exception e) {
            e.printStackTrace();
            for(int i = 0; i < e.getStackTrace().length; i++)
            log.debug(e.getStackTrace()[i]);
            return ERROR;
        }

        return SUCCESS;
    }

    public List<TransportBooking> getReportsList() {
        return reportsList;
    }

    public void setReportsList(List<TransportBooking> reportsList) {
        this.reportsList = reportsList;
    }
   

    public void setSession(Map session) {
          this.session = session;
      }

      public Map getSession() {
          return session;
      }
   
   

}

Also note that the above is for illustrative purposes- In reallife we cannot recompile the jasper report for every user this could lead to a terrible bottle-neck in programs!

The other Jasper actions are similar we just change the output in the @Results as is shown for JasperExcelAction.java

package za.co.transporter.transportbooking.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.ResultPath;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.views.jasperreports.*;

import net.sf.jasperreports.engine.JasperCompileManager;

import za.co.transporter.transportbooking.model.TransportBooking;

import com.opensymphony.xwork2.ActionSupport;

@Result(name=”success”, type=”jasper”, params={“location”, “/transportbooking_template.jasper”, “dataSource”, “reportsList”, “format”, “XLS”,”documentName”,”transportbooking.xls” })
public class JasperExcelAction extends ActionSupport implements SessionAware{

    /** List to use as our JasperReports dataSource. */
    private List<TransportBooking> reportsList;
  
    private Map session;
   
    private static final Log  log              = LogFactory.getLog(JasperAction.class);
   
    public String execute() throws Exception {

        log.debug(“Creating Reporting”);      
        log.debug(reportsList);     
     
        reportsList = (List<TransportBooking>) getSession().get(“reportsList”);
        // Normally we would provide a pre-compiled .jrxml file
        // or check to make sure we don’t compile on every request.
        try {
            JasperCompileManager.compileReportToFile(
                    “F:/programming-tools/apache-tomcat-7.0.2/webapps/web-deploy/transportbooking_template.jrxml”,
                    “F:/programming-tools/apache-tomcat-7.0.2/webapps/web-deploy/transportbooking_template.jasper”);
        } catch (Exception e) {
            e.printStackTrace();
            for(int i = 0; i < e.getStackTrace().length; i++)
            log.debug(e.getStackTrace()[i]);
            return ERROR;
        }

        return SUCCESS;
    }

    public List<TransportBooking> getReportsList() {
        return reportsList;
    }

    public void setReportsList(List<TransportBooking> reportsList) {
        this.reportsList = reportsList;
    }
   

    public void setSession(Map session) {
          this.session = session;
      }

      public Map getSession() {
          return session;
      }
   
   

}

The folder for our web application which I will call web-deploy has the structure:

The web-xml looks like:

<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app id=”struts2-jquery-showcase” version=”2.4″ xmlns=”http://java.sun.com/xml/ns/j2ee&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd”&gt;

    <display-name>PaltrackTransportBookingDemo</display-name>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

The grid.jsp web page is where are the events take place:

<%@ taglib prefix=”s” uri=”/struts-tags”%>
<%@ taglib prefix=”sj” uri=”/struts-jquery-tags”%>
<%@ taglib prefix=”sjg” uri=”/struts-jquery-grid-tags”%>

<script type=”text/javascript”>
    datePick = function(elem) {
        $(elem).datepicker();
        $(‘#ui-datepicker-div’).css(“z-index”, 2000);
    }
</script>
<s:url id=”remoteurl” action=”json-table” />
    <s:url id=”editurl” action=”edit-transport-booking” />
        <s:url id=”pdfreporturl” action=”jasper” /> 
            <s:url id=”excelreporturl” action=”jasper-excel” />
            <s:url id=”csvreporturl” action=”jasper-csv” />
            <s:url id=”htmlreporturl” action=”jasper-html” />
    <sjg:grid
        id=”transportbookingtable”
        caption=”TransportBooking (Editable/Multiselect)”
        dataType=”json”
        href=”%{remoteurl}”
        pager=”true”
        navigator=”true”
        navigatorSearch=”true”
        navigatorSearchOptions=”{multipleSearch:true}”       
        navigatorAddOptions=”{
            height:280,
            reloadAfterSubmit:true,
            afterSubmit:function(response, postdata) {
                            return isError(response.responseText);
                         }
        }”
        navigatorEdit=”true”
        navigatorEditOptions=”{
            height:280,
            reloadAfterSubmit:true,
            afterSubmit:function(response, postdata) {
                            return isError(response.responseText);
                         }
        }”
        navigatorView=”true”
        navigatorDelete=”true”
        navigatorDeleteOptions=”{
            height:280,
            reloadAfterSubmit:true,
            afterSubmit:function(response, postdata) {
                            return isError(response.responseText);
                         }
        }”
        gridModel=”gridModel”
        rowList=”10,15,20″
        rowNum=”15″
        editurl=”%{editurl}”
        editinline=”false”
        multiselect=”true”
        viewrecords=”true”
    >
        <sjg:gridColumn name=”bookingId”
            index=”bookingId”
            key=”true”
            title=”ID”
            width=”50″
            formatter=”integer”
            sortable=”true”
            search=”true”
            searchoptions=”{sopt:[‘eq’,’ne’,’lt’,’gt’,’le’,’ge’]}”
        />
        <sjg:gridColumn
            name=”name”
            index=”name”
            title=”name”
            width=”300″
            sortable=”true”
            editable=”true”
            edittype=”text”
            search=”true”
            searchoptions=”{sopt:[‘eq’,’ne’,’lt’,’gt’,’le’,’ge’]}”
        />
        <sjg:gridColumn
            name=”phone”
            index=”phone”
            title=”phone”
            sortable=”true”
            editable=”true”
            edittype=”text”
            search=”true”
            searchoptions=”{sopt:[‘eq’,’ne’,’lt’,’gt’,’le’,’ge’]}”
            />
        <sjg:gridColumn
            name=”cellnumber”
            index=”cellnumber”
            title=”cellnumber”
            sortable=”true”
            editable=”true”
            edittype=”text”
            search=”true”
            searchoptions=”{sopt:[‘eq’,’ne’,’lt’,’gt’,’le’,’ge’]}”
            /> 
        <sjg:gridColumn
            name=”confirmBy”
            index=”confirmBy”
            title=”confirmBy”
            sortable=”true”
            editable=”true”
            edittype=”text”
            editoptions=”{size: 19, maxlength: 19, dataInit:datePick }”
            formatter=”date”
            formatoptions=”{newformat : ‘d.m.Y H:i’, srcformat : ‘Y-m-d H:i:s’}”
            width=”90″           
            search=”true”
            searchoptions=”{sopt:[‘eq’,’ne’,’lt’,’gt’,’le’,’ge’], dataInit:datePick, attr:{title:’Your Search Date’}}”
            />
        <sjg:gridColumn
            name=”transport”
            index=”transport”
            title=”transport”
            sortable=”true”
            editable=”true”
            edittype=”text”
            search=”true”
            searchoptions=”{sopt:[‘eq’,’ne’,’lt’,’gt’,’le’,’ge’]}”
            />
    </sjg:grid>
   
    <br>
    <br>
    <br>
    <br>  
 <div id=”nav”>
      <div class=”hlist ui-widget-header”>
         <ul>
 <li class=”ui-widget-header”><s:a id=”reportlink” href=”%{pdfreporturl}” >PDF Report</s:a></li>
 <li class=”ui-widget-header”><s:a id=”reportlink” href=”%{excelreporturl}” >Excel Report</s:a></li>
 <li class=”ui-widget-header”><s:a id=”reportlink” href=”%{csvreporturl}” >CSV Report</s:a></li>
 <li class=”ui-widget-header”><s:a id=”reportlink” href=”%{pdfreporturl}” >HTML Report</s:a></li>
         </ul>
       </div>
     </div>

Here you can see how to add date pickers and filters for multiple criteria filters. Please not that I borrowed the theme from the showcase of the JQuery examples at http://www.weinfreund.de/struts2-jquery-showcase/index.action.

The end result is as follows:

The relevant libraries needed to build the project:

Enjoy! If you have any queries or would like more source code please email me and I can email you the source code zipped.

Advertisements

About gjcbell

I'm a software designer and integration specialist in Cape Town, South Africa. I work for SPF at SGH. I develop applications in Java, Cplusplus and Python and JavaScript. I design websites and web applications.
This entry was posted in Uncategorized. Bookmark the permalink.

16 Responses to Struts 2 and JQuery Example project with Jasper for Reporting

  1. Pingback: Struts 2 and JQuery Example project with Jasper for Reporting

  2. Thank you for this great Tutorial!

    Do you think there is an easy and generic way to integrate the export feature to struts2 jQuery grid without extra export actions?

    Like:

    • gjcbell says:

      Hi Johannes,

      Thank you for the reply.

      I think we could use the JsonTableAction.java and have multiple results in other words we must be able to return not only a result type “json” but also “jasper”.

      We could have :

      @Results({
      @Result(type=”json”),
      @Result(name=”success”, type=”jasper”, params={“location”, “/table_template.jasper”, “dataSource”, “reportsList”, “format”, “XLS”,”documentName”,”table.xls” })
      })

      In the action we can have a method that can create the report.

      I will have to test it though.

      Please give feedback on your thoughts about this.

      kind regards,

      Gabriel

  3. Can you post a link to a zipped project file?

  4. Carolina says:

    Congratulations for the tutorial!!!!
    Can you email me a project??
    Thank you.

  5. aniello says:

    Hi,
    thank you for this great post,
    could you email me the sources, i’d like to dive into it.

    k r
    Aniello

  6. hernez says:

    Very nice project. well done. It puts things in perspective. Thank you. I have enjoyed a lot.

  7. dinolee says:

    Hi,
    thank you for this great post,
    could you email me the sources
    dino0818@163.com

  8. Mukesh says:

    Hi Gabriel,

    I am new to Struts2. I have been through several examples of Struts2 and jquery but could not find any good project which helps me learn professional things.

    I liked your project very much, could you please send me your ‘Struts 2 and JQuery Example project with Jasper for Reporting’ and other good projects which you think can help me.

    I would be really thankful to you.

    my email – mukeshh.verma@gmail.com

    Thanks in advance,
    Mukesh
    mukeshh.verma@gmail.com

  9. hihi says:

    can i’ve the source code of this application please 🙂

  10. Jayavardhan says:

    Hi
    this tutorial is very helpful, please send me the source code

  11. Amit Parmar says:

    Hi! Thanks for the tutorial. Can you please send or post the source code? Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s