1

Spring MVC 3.1 アプリケーションで、リクエストのロケールを使用して HttpMessageConverter による文字列の書式設定を制御するにはどうすればよいですか?

土壌タイプを表すこの列挙型があります (抜粋):

public enum Soil {

    SAND("0.35"),
    PEAT("0.70");

    private Double porosity;

    Soil(String porosity) {
        this.porosity = new Double(porosity);
    }

    @NumberFormat(pattern = "0.000")
    public Double getPorosity() {
        return porosity;
    }

}

土壌のプロパティにアクセスするためのコントローラーもあります。これは、異なる土壌タイプが選択されたときにトリガーされる ajax リクエストを処理しています。

@Controller
@RequestMapping("/soil/*")
public class SoilController {

    @RequestMapping(value="{id}/porosity")
    public @ResponseBody Double getPorosity(@PathVariable String id) {
        Soil soil = Soil.valueOf(id);
        return soil.getPorosity();
    }

}

私が理解しているように、@RequestBody を使用することで、Spring は返された Double を HttpMessageConverter を使用して応答本文に変換します。これは正常に機能しますが、応答文字列は常にデフォルトのロケールを使用してフォーマットされます。たとえば、/soil/PEAT/porosity への GET 要求は、応答本文に「0.7」が書き込まれます。

ただし、ほとんどの訪問者は、小数点の代わりに小数点のコンマを期待して、優先ロケールとして「nl」を持っています。この場合、応答文字列を「0,7」の形式にしたいと思います。

ハンドラー メソッドの署名に HttpServletRequest パラメーターを追加して、要求のロケールを特定できますが、この情報を HttpMessageConverter (この場合は MappingJacksonHttpMessageConverter) に渡す方法がわかりません (*)。タグのデフォルトをオーバーライドすることで MappingJacksonHttpMessageConverter Bean を構成できることはわかっていますが、リクエスト ロケールを認識させるにはどうすればよいですか?

(*) DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - [org.springframework.http.converter.json. MappingJac ksonHttpMessageConverter@145240a]

ワーキングソリューション

@CodeChimp が指摘したように ( https://stackoverflow.com/a/15074077/1343409 )、i18n フォーマットはビューで処理するのが最適です。

ハンドラーメソッドを次のように変更しました

@RequestMapping(value="{id}/porosity")
public String getPorosity(@PathVariable String id, HttpServletRequest request, Model model) {
    Soil soil = Soil.valueOf(id);
    model.addAttribute("doubleValue", soil.getPorosity());
    return "basevalues/double";         
}

シンプルな JSTL ビュー double.jsp を追加しました

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page contentType="text/plain;charset=UTF-8" %>
<fmt:formatNumber type="number" value="${doubleValue}"/>

これは私にとってはうまくいきます。

4

1 に答える 1

0

ResponseBody アノテーションは、返されたものを何でも取得し、それを応答本文に挿入するように Spring に指示します。1 対 1 で行われ、変換はありません。たとえば、バイナリ イメージ データ、CSV ファイルなどを返すためにその注釈を使用しました。特定のロケール用にフォーマットされた数値を返したい場合は、getPorosity() メソッドでチェックを行い、そこに適切な変更を加えます。

編集して情報を追加

HttpMessageConverter についての私の理解は、HTTP 要求/応答との間の変換に使用されるということです。HttpMessageConverter は、それ自体が多くの実装を持つ単なるインターフェースです。適切な実装は、リクエスト/レスポンス ヘッダーと使用しているリターンのタイプに基づいて選択されます。たとえば、リクエストで application/xml または text/xml を受け入れるように指定されている場合、MarshallingHttpMessagingConverter を使用して、戻り値を適切な XML 形式に変換します。

ただし、@ResponseBody アノテーションを使用すると、変換を回避できます。このアノテーションは基本的に、Spring に対して「戻り値の型の変換について心配する必要はありません。返されたものを取得して、応答本文に押し込んでください」と示しています。

HttpMessageConverter を実装するクラスがロケールにまったく関係しているとは思いません。彼らの唯一の関心事は、戻り値の型を取得し、それを転送用の適切な形式に変換することです。ロケールに依存する i18n 関連のアイテムの処理は、ビューに関連する問題であり、私の経験では、ビューで処理するのが最適です。

于 2013-02-25T18:43:59.413 に答える