3

Spring Roo の強みは、難しいことを処理できることです。

質問: 地球上のどこに住んでいようと、各ユーザーに現地時間で日付を表示する方法に関する優れたベスト プラクティスと実装がある場合。

問題: ユーザーが日付を入力して「すべての訪問のリスト」ページに移動すると、OpenShift サーバーとは異なるタイムゾーンにいる場合、合計で異なる日付が表示されます。たとえば、私は GMT+1 (西ヨーロッパ) タイムゾーンにいます。

ここに画像の説明を入力

私の状況:

  1. WebアプリケーションはSpring Roo 2.0 / gvNIX 2.0で開発
  2. OpenShift (rhcloud.com) でホストされます。petclinic サンプルと同様: 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ビューの解決策/提案について説明します。しかし、同じ方法で他のビューにも実装できます。

変更の本質は、timeZone をWEB-INF/tags/form/fields/column.tagx/display.jspxの fmt : formatDate .. ステートメントに追加したことです。

年:

<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) コントローラーで、timeZone を次のように指定します。

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 に答える