2 Replies Latest reply on Feb 6, 2007 8:17 AM by Juha Moisio

    JBSEAM-317 s:link tag creates url with double '?' mark

    Juha Moisio Newbie

      Hi,

      I just upgraded from 1.0 to 1.1.5GA and I'm still having problems with <s:link>. It still generates urls with two ? marks.

      Any idea?


      Br,

      Juha

        • 1. Re: JBSEAM-317 s:link tag creates url with double '?' mark
          Pete Muir Master

          It would probably help if you were able to add a testcase to the jira issue

          • 2. Re: JBSEAM-317 s:link tag creates url with double '?' mark
            Juha Moisio Newbie

            Yes, I know.. :) I can try to create one.

            Here is my code where the problem occurs:

            <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
            <ui:composition xmlns="http://www.w3.org/1999/xhtml"
             xmlns:ui="http://java.sun.com/jsf/facelets"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:s="http://jboss.com/products/seam/taglib"
             xmlns:t="http://myfaces.apache.org/tomahawk" template="template.xhtml">
            
             <ui:define name="pagemain">
            
             <h:form>
            
             <table class="noborder">
             <tr>
             <td>#{msgs.chain}:</td>
             <td><h:selectOneMenu value="#{deliveryReport.search1}"
             converter="#{chainSelect.converter}">
             <f:selectItems value="#{chainSelect.chainList2}" />
             </h:selectOneMenu> </td>
             <td>#{msgs.filename}:</td>
             <td><h:inputText value="#{deliveryReport.search2}" /> </td>
             <td>#{msgs.notes}:</td>
             <td><h:inputText value="#{deliveryReport.search3}" /> </td>
            
            
             </tr>
             <tr>
             <td>#{msgs.from}:</td>
             <td><t:inputDate value="#{deliveryReport.date1}" type="date"
             popupCalendar="true" ampm="true" /> </td>
             <td>#{msgs.to}:</td>
             <td><t:inputDate value="#{deliveryReport.date2}" type="date"
             popupCalendar="true" ampm="true" /> </td>
             <td colspan="2"><h:commandButton class="button" type="submit"
             value="#{msgs.find}" action="#{deliveryReport.findFirstPage}" /> </td>
             </tr>
             </table>
            
             <br />
             <br />
             <h:outputText styleClass="caption"
             value="#{msgs.nostatusesfound}"
             rendered="#{deliveryReport.noMessages}" />
            
             <h:outputText styleClass="caption"
             value="#{deliveryReport.reportData.chainDescription}"
             rendered="#{deliveryReport.reportData.summariesByDate != null}" />
             <br />
             <br />
            
             <ui:repeat value="#{deliveryReport.reportData.summariesByDate}"
             var="bydate"
             rendered="#{deliveryReport.reportData.summariesByDate != null || deliveryReport.reportData.summariesByDate.size > 0}">
            
             <h:outputText styleClass="caption" value="#{bydate.date}">
             <f:convertDateTime timeZone="#{helper.timeZone}" type="date"
             dateStyle="medium" timeStyle="medium" />
             </h:outputText>
             <br />
             <br />
            
             <table border="0" width="600" cellspacing="1" cellpadding="0">
             <thead>
             <tr>
             <th class="caption">#{msgs.eventdate}</th>
             <th class="caption">#{msgs.eventtime}</th>
             <th class="caption">#{msgs.filename}</th>
             <th class="caption"> </th>
             </tr>
            
             </thead>
             <tbody>
             <br />
             <ui:repeat value="#{bydate.summaries}" var="s">
            
             <tr>
             <td class="td100"><h:outputText value="#{s.eventdate}">
             <f:convertDateTime timeZone="#{helper.timeZone}" type="date"
             dateStyle="medium" />
             </h:outputText></td>
             <td class="td100"><h:outputText value="#{s.eventtime}">
             <f:convertDateTime timeZone="#{helper.timeZone}" type="time"
             timeStyle="medium" />
             </h:outputText></td>
            
             <td class="td300">#{s.filename}</td>
            
             <td class="td100"><s:link
             action="#{deliveryReportDetails.showDetails}"
             value="[ #{msgs.details} ]">
             <f:param name="summaryid" value="#{s.id}" />
             </s:link></td>
            
             </tr>
             </ui:repeat>
            
             <tr>
             <td span="4"> </td>
             </tr>
            
             <tr>
             <td span="4">#{msgs.total}: <h:outputText
             value="#{bydate.deliveredMessages}" /></td>
             </tr>
            
             </tbody>
             </table>
             <br />
             </ui:repeat>
            
             <table width="300" class="noborder">
             <tr>
             <td align="left" class="td150"><h:commandButton class="button"
             action="#{deliveryReport.findPreviousPage}"
             value="#{msgs.previouspage}"
             rendered="#{deliveryReport.previousPage}" /></td>
             <td align="left" class="td150"><h:commandButton class="button"
             action="#{deliveryReport.findNextPage}" value="#{msgs.nextpage}"
             rendered="#{deliveryReport.nextPage}" /></td>
             </tr>
             </table>
            
             <br />
             <br />
            
             </h:form>
            
             </ui:define>
            
             <ui:define name="pagemenu">
             </ui:define>
            
            </ui:composition>
            
            


            This s:link

            <s:link action="#{deliveryReportDetails.showDetails}"value="[ #{msgs.details} ]"><f:param name="summaryid" value="#{s.id}" /> </s:link>
            


            Generates link with url

            http://webtech/ServiceConsole/deliveryreport.jsf?summaryid=1103769?actionMethod=deliveryreport.xhtml%3AdeliveryReportDetails.showDetails&cid=16
            



            And the action bean is

            package fi.logiasoftware.messageserver.frontend;
            
            import java.io.Serializable;
            import java.util.Date;
            import java.util.HashMap;
            import java.util.List;
            import java.util.Map;
            import java.util.TimeZone;
            import java.util.Map.Entry;
            import javax.ejb.Remove;
            import javax.ejb.Stateful;
            import javax.interceptor.Interceptors;
            import javax.persistence.EntityManager;
            import javax.persistence.PersistenceContext;
            import javax.persistence.Query;
            import javax.persistence.TemporalType;
            import org.jboss.annotation.ejb.SerializedConcurrentAccess;
            import org.jboss.annotation.ejb.cache.simple.CacheConfig;
            import org.jboss.seam.ScopeType;
            import org.jboss.seam.annotations.Destroy;
            import org.jboss.seam.annotations.Factory;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.annotations.Scope;
            import org.jboss.seam.ejb.SeamInterceptor;
            import fi.logiasoftware.messageserver.config.Chain;
            import fi.logiasoftware.messageserver.config.Summary;
            import fi.logiasoftware.messageserver.services.common.Util;
            
            /**
             *
             * This class is a Stateful bean.It is used to view summarynotes of a specific
             * summary.
             *
             * @Stateful
             * @Name("deliveryReport")
             * @Scope(ScopeType.SESSION)
             * @SerializedConcurrentAccess
             * @Interceptors(SeamInterceptor.class)
             *
             * @CacheConfig(idleTimeoutSeconds=1800)
             *
             *
             * implements Serializable, DeliveryReport
             *
             *
             *
             * @author hbm2java (latest modification by $Author: sam $)
             * @version $Revision: 1.14 $ $Date: 2006/10/20 08:51:04 $
             */
            @Stateful
            @Name("deliveryReport")
            @Scope(ScopeType.SESSION)
            @CacheConfig(idleTimeoutSeconds = 1800)
            @Interceptors(SeamInterceptor.class)
            @SerializedConcurrentAccess
            public class DeliveryReportBean implements Serializable, DeliveryReport {
            
             private static final long serialVersionUID = 1L;
            
             @PersistenceContext(unitName = "MessageServer")
             private EntityManager em;
            
             private int pageSize = 1;
             private int pageNumber = 0;
             private int numberOfPages = 0;
             private DeliveryReportData reportData;
             private Chain search1 = new Chain();
             private Date date1;
             private Date date2;
             private String search2;
             private String search3;
             private boolean noMessages = false;
            
             /**
             * Set reportData to null and set dates
             */
            
             public String begin() {
             date1 = Util.getNow();
             date2 = Util.getNow();
             reportData = null;
            
             return "delivery_report";
             }
             /**
             *
             * @return value on noMessages as boolean
             */
             public boolean getNoMessages(){
             return this.noMessages;
             }
            
             /**
             * Get value of search3 field
             */
             public String getSearch3() {
             return search3;
             }
            
             /**
             * Set value of search3 field
             */
             public void setSearch3(String search3) {
             if (search3.startsWith("*") == true || search3.endsWith("*") == true) {
             search3 = search3.replace('*', '%');
             }
             this.search3 = search3;
             }
            
             /**
             * Get value of search2 field
             */
             public String getSearch2() {
             return search2;
             }
            
             /**
             * Set value of search2 field
             */
             public void setSearch2(String search2) {
             if (search2.startsWith("*") == true || search2.endsWith("*") == true) {
             search2.replace('*', '%');
             }
             this.search2 = search2;
             }
            
             /**
             * Get reportData
             */
             public DeliveryReportData getReportData() {
             return reportData;
             }
            
             /**
             * Set reportData
             */
             public void setReportData(DeliveryReportData reportData) {
             this.reportData = reportData;
             }
            
             /**
             * Get TimeZone
             */
             public TimeZone getTimeZone() {
             return TimeZone.getDefault();
             }
            
             /**
             * Get date1
             */
             public Date getDate1() {
             return date1;
             }
            
             /**
             * Set date1
             */
             public void setDate1(Date date1) {
             this.date1 = date1;
             }
            
             /**
             * Get date2
             */
             public Date getDate2() {
             return date2;
             }
            
             /**
             * Set date2
             */
             public void setDate2(Date date2) {
             this.date2 = date2;
             }
            
             /**
             * Get value of search1 field
             */
             public Chain getSearch1() {
             return search1;
             }
            
             /**
             * Set value of search1 field
             */
             public void setSearch1(Chain newValue) {
             this.search1 = newValue;
             }
            
             /**
             * Get pageSize
             */
             public int getPageSize() {
             return pageSize;
             }
            
             /**
             * Set pageSize
             */
             public void setPageSize(int pageSize) {
             this.pageSize = pageSize;
             }
            
             /**
             * @return : boolean value is there previous page
             */
             public boolean isPreviousPage() {
             return reportData != null && pageNumber > 0;
             }
            
             /**
             * @return : boolean value is there next page
             */
             public boolean isNextPage() {
             return reportData != null && reportData.getSummariesByDate() != null
             && numberOfPages - 1 > pageNumber;
             }
            
             /**
             * Creates and executes query to get Summary's pageSize is the amount of
             * results showed on each page. Results are grouped by eventdate.
             *
             */
             @SuppressWarnings("unchecked")
             public void executeQuery() {
             noMessages = false;
             Map<String, Object> parameters = new HashMap<String, Object>();
             Chain chain = em.find(Chain.class, search1.getId());
            
             StringBuffer queryString = new StringBuffer();
             queryString.append("from Summary s where");
            
             reportData = new DeliveryReportData();
             reportData.setChainDescription(chain.getDescription());
             queryString.append(" s.chain = :chain");
             parameters.put("chain", chain);
             queryString.append(" and s.eventdate >= :date1");
             parameters.put("date1", getDate1());
             queryString.append(" and s.eventdate <= :date2");
             parameters.put("date2", getDate2());
            
             if (search2 != null && search2.length() > 0) {
             queryString.append(" and s.filename like :search2");
             parameters.put("search2", getSearch2());
             }
             if (search3 != null && search3.length() > 0) {
             queryString.append(" and s.summarynoteses.note like :search3");
             parameters.put("search3", getSearch3());// + "%");
             }
            
             queryString.append(" group by s.eventdate");
            
             Query query = em.createQuery(queryString.toString());
            
             for (Entry<String, Object> param : parameters.entrySet()) {
            
             if (param.getValue() instanceof Date) {
             query.setParameter(param.getKey(), (Date) param.getValue(),
             TemporalType.TIMESTAMP);
             } else {
             query.setParameter(param.getKey(), param.getValue());
             }
             }
             numberOfPages = query.getResultList().size(); // antaa sivujen kpl
             List<Summary> summaryDates = query.setMaxResults(pageSize)
             .setFirstResult(pageSize * pageNumber).getResultList();
            
             String secondQuery = "from Summary s where s.chain = :chain and s.eventdate = :date";
            
             if (search2 != null && search2.length() > 0) {
             secondQuery = secondQuery + " and s.filename like :search2";
             }
             if (search3 != null && search3.length() > 0) {
             secondQuery = secondQuery
             + " and s.summarynoteses.note like :search3";
             }
            
             for (Summary s : summaryDates) {
            
             Query q = em.createQuery(secondQuery).setParameter("date",
             s.getEventdate()).setParameter("chain", chain);
            
             if (search2 != null && search2.length() > 0) {
             q.setParameter("search2", search2 + "%");
             }
             if (search3 != null && search3.length() > 0) {
             q.setParameter("search3", search3 + "%");
             }
            
             List<Summary> summaries = q.getResultList();
            
             if (summaries != null && summaries.size() > 0) {
             reportData.addSummary(s.getEventdate(), summaries);
             }
             }
            
             if (reportData == null || summaryDates == null || summaryDates.size() == 0) {
             noMessages = true;
             }
             }
            
             /**
             *
             * calls executeQuery to get data for first page
             *
             * @Factory("reportData")
             */
             @Factory("reportData")
             public String findFirstPage() {
             reportData = null;
             pageNumber = 0;
             executeQuery();
             return "delivery_report";
             }
            
             /**
             * calls executeQuery to get data for nextpage
             */
             public String findNextPage() {
             if (pageNumber + 1 < numberOfPages) {
             pageNumber++;
             executeQuery();
             return "delivery_report";
             } else {
             return null;
             }
             }
            
             /**
             * calls executeQuery to get data for previouspage
             */
             public String findPreviousPage() {
             if (pageNumber - 1 >= 0) {
             pageNumber--;
             executeQuery();
             return "delivery_report";
             } else {
             return null;
             }
             }
            
             /**
             * If reportData is not null calls executeQuery to refress page.
             */
             public void refresh() {
             if (reportData != null)
             executeQuery();
             }
            
             /**
             * Removes and destroys
             */
             @Remove
             @Destroy
             public void destroy() {
             reportData = null;
             }
            
            }
            
            




            -Juha-