3

Spring Roo 的强大之处在于它可以处理困难的事情。

问题:如果有一个很好的最佳实践和实施,如何向每个用户显示,无论他住在这个星球上的哪个地方,当地时间的日期。

问题:当用户输入日期并转到“列出所有访问”页面时,如果他/她与 OpenShift 服务器处于不同的时区,他/她将看到完全不同的日期。例如,我在 GMT+1(西欧)时区。

在此处输入图像描述

我的情况:

  1. 使用 Spring Roo 2.0 / gvNIX 2.0 开发 Web 应用程序
  2. 将托管在 OpenShift (rhcloud.com) 上与宠物诊所样本一样:https ://petclinic-gvnix.rhcloud.com/
  3. 用户可以生活在世界各地,所以每个时区。
  4. Java 8 目前不是一个选项,因为 OpenShift 还没有部署 TomCat 8,如果可能的话,我想避免创建 OpenShift DIY 应用程序。

要求:

  1. 每个用户都应该看到其当地时间的日期。

复制:

  1. 转到 Petclinic 示例并登录:https ://petclinic-gvnix.rhcloud.com/
  2. 选择访问 -> 创建新访问
  3. 选择列出所有访问

当您处于与 Openshift 服务器不同的时区时,您会得到类似上面的内容

4

1 回答 1

0

考虑到这个问题后,我认为我有一个干净的解决方案可以在不影响当前项目的情况下实现时区支持。

我的出发点是解决方案应该是向后兼容的,并且不应该破坏当前的项目。此外,更改应尽可能少。

我对其进行了测试并且它可以工作,当我的 Web 应用程序在 Openshift 上运行时,它也托管在 TimeZone GMT-5:00 和我住在西欧,GMT +1:00

请给我你的意见。

我将描述show.jspx视图的解决方案/建议。但以同样的方式,它也可以用于其他视图。

更改的本质是我在WEB-INF/tags/form/fields/column.tagx/display.jspx的 fmt:formatDate .. 语句中添加了 timeZone :

老的:

<fmt:formatDate value="${object[field]}" pattern="${fn:escapeXml(dateTimePattern)}" />

新的:

<fmt:timeZone value="${timeZone}">
    <fmt:formatDate value="${object[field]}" pattern="${fn:escapeXml(dateTimePattern)}" timeZone="${timeZone}" />
</fmt:timeZone>

为此,我还添加了声明和不使用时的默认 timeZone 设置。

<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:fmt="http://java.sun.com/jsp/jstl/fmt" xmlns:spring="http://www.springframework.org/tags" xmlns:form="http://www.springframework.org/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
  <jsp:output omit-xml-declaration="yes" />

  <jsp:directive.attribute name="id" type="java.lang.String" required="true" rtexprvalue="true" description="The identifier for this tag (do not change!)" />
  <jsp:directive.attribute name="object" type="java.lang.Object" required="true" rtexprvalue="true" description="The form backing object" />
  <jsp:directive.attribute name="field" type="java.lang.String" required="true" rtexprvalue="true" description="The field name" />
  <jsp:directive.attribute name="label" type="java.lang.String" required="false" rtexprvalue="true" description="The label used for this field, will default to a message bundle if not supplied" />
  <jsp:directive.attribute name="date" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate that this field is of type java.util.Date" />
  <jsp:directive.attribute name="calendar" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate that this field is of type java.util.Calendar" />
  <jsp:directive.attribute name="dateTimePattern" type="java.lang.String" required="false" rtexprvalue="true" description="The date / time pattern to use if the field is a date or calendar type" />

  ========== Added declaration
  <jsp:directive.attribute name="timeZone" type="java.lang.String" required="false" rtexprvalue="true" description="The timezone to use if the field is a date or calendar type" />
  ========== End

  <jsp:directive.attribute name="render" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate if the contents of this tag and all enclosed tags should be rendered (default 'true')" />
  <jsp:directive.attribute name="z" type="java.lang.String" required="false" description="Used for checking if element has been modified (to recalculate simply provide empty string value)" />

  <c:if test="${empty render or render}">
    <c:if test="${not empty object and empty label}">
      <spring:message code="label_${fn:toLowerCase(fn:substringAfter(id,'_'))}" var="label" htmlEscape="false" />
    </c:if>

    <c:if test="${empty dateTimePattern}">
      <c:set value="MM/dd/yyyy" var="dateTimePattern" />
    </c:if>

    ========== Added default setting. Taking the timezone of the server!
    <c:if test="${empty timeZone}">
        <jsp:scriptlet>
            jspContext.setAttribute("timeZone", java.util.TimeZone.getDefault().getID());
        </jsp:scriptlet>
    </c:if>
  ========== End

    <div id="_${fn:escapeXml(id)}_id">
      <label for="_${fn:escapeXml(field)}_id">
        <c:out value="${label}" />
        :
      </label>
      <div class="box" id="_${fn:escapeXml(id)}_${fn:escapeXml(field)}_id">
        <c:choose>
          <c:when test="${date}">
            <spring:escapeBody>

    ========== Changed: added timeZone support for Date
              <fmt:timeZone value="${timeZone}">
                <fmt:formatDate value="${object[field]}" pattern="${fn:escapeXml(dateTimePattern)}" timeZone="${timeZone}" />
              </fmt:timeZone>
  ========== End

            </spring:escapeBody>
          </c:when>
          <c:when test="${calendar}">
            <spring:escapeBody>

    ========== Changed: added timeZone support for Calendar
              <fmt:timeZone value="${timeZone}">
                    <fmt:formatDate value="${object[field].time}" pattern="${fn:escapeXml(dateTimePattern)}" timeZone="${timeZone}" />
              </fmt:timeZone>
  ========== End

            </spring:escapeBody>
          </c:when>
          <c:otherwise>
            <spring:eval expression="object[field]" />
          </c:otherwise>
        </c:choose>
      </div>
    </div>
    <br />
  </c:if>
</jsp:root>

添加/更改这几行时,所有旧代码将继续工作。您还必须将这些更改应用到WEB-INF/tags/form/fields/column.tagx文件。

我使用 gvNIX JQuery,同样的更改也应该在那里应用。

这就是你必须做的所有改变!!!!

要在所有 show.jspx 文件中添加时区支持: 1) 为任何日期添加额外的时区选项。

老的:

<field:display date="true" dateTimePattern="${fileUpload_uploaddate_date_format}" field="uploadDate" id="s_com_myproject_onlineviewer_domain_FileUpload_uploadDate" object="${fileupload}" z="user-managed"/>

新的:

     <field:display date="true" dateTimePattern="${fileUpload_uploaddate_date_format}" field="uploadDate" id="s_com_myproject_onlineviewer_domain_FileUpload_uploadDate" object="${fileupload}" timeZone="${fileUpload_uploaddate_date_timezone}" z="user-managed"/>

2)在您的控制器中指定您的时区,例如:

uiModel.addAttribute("fileUpload_uploaddate_date_timezone", "Europe/Amsterdam");

本着 Spring Roo 数据格式的精神 addDateTimeFormatPatterns(uiModel); 我添加了addTimeZone(uiModel); .

在此方法中,您可以指定时区的来源。在我的 Web 应用程序中,我要求用户在重新注册时指定他/她的时区。所有其他解决方法都在某处失败。

    void addTimeZone(Model uiModel) {
    uiModel.addAttribute("fileUpload_uploaddate_date_timezone", UserUtils.geTimeZone());
}

顺便说一句,AspectJ 控制器中的addTimeZone默认方法可以如下面的示例所示,让程序员能够推入和更改它。

void FileUploadController.addTimeZone(Model uiModel) {
uiModel.addAttribute("fileUpload_uploaddate_date_timezone", TimeZone.getDefault().getID());

}

于 2015-11-21T15:37:06.087 回答