8

HashMap またはその他の Map 実装を ajax から Spring MVC コントローラーに送信しようとしています。

これが私がそれを行う方法の詳細です:

Ajax呼び出しは次のとおりです

var tags = {};
tags["foo"] = "bar";
tags["whee"] = "whizzz";


$.post("doTestMap.do",   {"tags" : tags }, function(data, textStatus, jqXHR) {
if (textStatus == 'success') {
    //handle success
    console.log("doTest returned " + data);
} else {
    console.err("doTest returned " + data);
}
}); 

次に、コントローラー側に次のものがあります。

@RequestMapping(value="/publisher/doTestMap.do", method=RequestMethod.POST)
public @ResponseBody String doTestMap(@RequestParam(value = "tags", defaultValue = "") HashMap<String,String> tags, HttpServletRequest request) {  //

    System.out.println(tags);

    return "cool";
} 

残念ながら、私は体系的に取得します

org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Map]: no matching editors or conversion strategy found

私は何を間違っていますか?

ありがとうございました。

4

5 に答える 5

13

スプリング コントローラーでのマップのバインドは、配列のバインドと同じ方法でサポートされます。専用コンバータ不要!

ただし、次の点に注意してください。

  • Springコマンドオブジェクトをトップ レベルの値ホルダーとして使用します。コマンド オブジェクトは任意のクラスにすることができます。

必要なのは、タグと呼ばれるTagsWrapperタイプのフィールドを保持するラッパー クラス ( )だけです。Map<String, String>配列をバインドするのと同じアプローチ。

これはドキュメントでかなりよく説明されていますが、時々ラッパーオブジェクトの必要性を忘れていました;)

2 番目に変更する必要があるのは、タグの値を送信する方法です。

  • 完全なマップの完全な文字列表現ではなく、マップ キーごとに 1 つのフォーム パラメータを使用してください。
  • 1 つの入力値は次のようになります。

      <input type="text" name="tags[key]" value="something">
    

タグがラッパー内のマップである場合、これはフォーム送信の箱から出して動作します。

于 2013-08-17T05:43:39.980 に答える
6

Martin Freyのヘルプに従って、コードを使用した私の完全な回答は次のとおりです。

JavaScript 側 (タグの値がどのように入力されるかに注意してください):

var data = {
   "tags[foo]" : "foovalue", 
   "tags[whizz]" : "whizzvalue" 
}

$.post("doTestMap.do",   data , function(data, textStatus, jqXHR) {
    ...
}); 

そして、コントローラー側で:

@RequestMapping(value="/publisher/doTestMap.do", method=RequestMethod.POST)
public @ResponseBody String doTestMap(@ModelAttribute MyWrapper wrapper, HttpServletRequest request) {
} 

その中に Map を含むラッパークラスを作成します。

class MyWrapper {

    Map<String,String> tags;

   +getters and setters

}

次に、マップに適切にデータが取り込まれます...

于 2013-08-17T16:02:20.387 に答える
5

これにより、応答が遅くなる可能性があります。しかし、それは誰かを助けるかもしれません。私は同様の問題を抱えていましたが、これが私がそれを修正した方法です。JS の場合: 私のマップは次のようになります。

var values = {};
values[element.id] = element.value;

アヤックス:

        $.ajax({
            type : 'POST',
            url : 'xxx.mvc',
            data : JSON.stringify(values),              
            error : function(response) {
                alert("Operation failed.");
            },
            success : function(response) {
                alert("Success");
            },
            contentType : "application/json",
            dataType : "json"
        });

コントローラ:

@RequestMapping(value = "/xxx.mvc", method=RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getValues(@RequestBody Map<String, Object> pvmValues, final HttpServletRequest request, final HttpServletResponse response) {
System.out.println(pvmValues.get("key"));
}
于 2014-10-03T14:40:25.933 に答える
0

tagsこれはデフォルトで、jQuery によって という名前の一連のパラメータとして URL エンコードされますtags[]。これがあなたが望んでいたものかどうかはわかりません。

spring には、同じ名前の複数のパラメーターから へのデフォルトの変換戦略がないため、エラーが発生しますHashMapListただし、それらを、配列、またはに簡単に変換できますSet

だからこれを試してください:

@RequestMapping(value="/publisher/doTestMap.do", method=RequestMethod.POST)
public @ResponseBody String doTestMap(@RequestParam(value = "tags[]") Set<String> tags, HttpServletRequest request) {  //

    System.out.println(tags); //this probably won't print what you want

    return "cool";
} 
于 2013-08-17T01:26:45.780 に答える
0

これを行う最善の方法は、JSON を使用してオブジェクトをエンコードし、デコードすることです。

2 つのライブラリが必要です。クライアント側ではjson2.jsが必要です。一部のブラウザーは、今ではネイティブにこれを行っているようです。しかし、これを持っている方が安全な方法です。

サーバーにはjacksonが必要です。

クライアントでマップをエンコードし、それをパラメーターとして渡します。

var myEncodedObject = JSON.stringify(tags);

サーバーでは、パラメーターを文字列として受け取り、デコードします。

ObjectMapper myMapper = new ObjectMapper();
Map<String, Object> myMap = myMapper.readValue(tags, new TypeReference<Map<String, Object>>);

Spring で自動的に変換する方法があるかもしれませんが、これが要点です。

于 2013-08-17T02:33:32.753 に答える