2016-06-20 7 views
1

私は前同様の質問をしてきた。今、私は似ていますが、別の問題を持っているthis oneグラブMVCのメソッドの引数として、JSONペイロードから特定のプロパティ

私のSpring MVCコントローラモデルは、残念なことに私のプロジェクトのクラスの一部ではない、定義済みの属性セットを持つJSONペイロードです。

など。

{ 
    "userId" : "john", 
    "role" : "admin" 
} 

私は別のString sとuserIdroleを治療する必要があります。

1)パラメータの組み合わせごとにカスタムDTOクラスを作成する必要があるため、私は現在、コントローラのメソッド

public ResponseObject mvc(@RequestBody MyCustomDTO dto){ 

    String userId = dto.getUserId(); 
    String role = dto.getRole(); 
} 

public ResponseObject mvc(@RequestBody ModelMap map){ 
    String userId = (String)map.get("userId"); 
    String role = (String)map.get("role"); 
} 

を宣言するには二つの方法があり、私は別の実装を見つけることが求められている(ほとんどの場合は1を必要とします例えばdelete(productId))、2)厳格に定義されていないエンティティが関与しています。特に、リストを扱うときには、実行時にチェックする必要のある任意の値を含めることができます。

私が見つけたように、Spring MVCはJSON要求本体から@ModelAttributeを解決することをサポートしていません。私は間違って何かをしているのですか?そうではありませんか?リクエストボディからメソッド引数に、特定のプロパティを取得できますか?それをプレーンプリミティブまたはPOJO全体にすることはできますか?

2番目のケースでは、Spring開発者に便利な機能をリクエストする方がよいでしょう。

春バージョンは4.2.xです。 この質問は以前にリンクされたものと関連していますが、今はJavascriptオブジェクトに単一のプロパティをカプセル化しているため、Jacksonが非直列化する必要があるオブジェクトはプリミティブではなくPOJOになります。

答えて

2

Spring MVCには組み込みツールがないため、個々のメンバーを簡単に取得することはできません。 1つのオプションは、例外のJSONオブジェクト本体のルートにパラメータを記述する独自のアノテーションを記述することです。次に、その注釈をハンドラメソッドパラメータに処理する新しいHandlerMethodArgumentResolver実装を作成して登録します。

これは簡単な作業ではありません。リクエストコンテンツは何度も使用することができないので、何とかして保存する必要があります(Filterなど)。今のところ、この制限を無視して、パラメータを1つだけ必要とすると仮定します。あなたは、アノテーション

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.PARAMETER) 
@interface JsonObjectProperty { 
    String name(); 
} 

、あなたが適切にJsonObjectPropertyResolverを登録する必要がありますHandlerMethodArgumentResolver

class JsonObjectPropertyResolver implements HandlerMethodArgumentResolver { 
    /** 
    * Configured as appropriate for the JSON you expect. 
    */ 
    private final ObjectMapper objectMapper = new ObjectMapper(); 

    @Override 
    public boolean supportsParameter(MethodParameter parameter) { 
     return parameter.hasParameterAnnotation(JsonObjectProperty.class); 
    } 

    @Override 
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, 
      WebDataBinderFactory binderFactory) throws Exception { 
     Class<?> parameterType = parameter.getParameterType(); 

     HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); 
     ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest); 
     MediaType contentType = inputMessage.getHeaders().getContentType(); 
     if (!contentType.equals(MediaType.APPLICATION_JSON_UTF8)) { 
      throw new HttpMessageNotReadableException(
        "Could not read document. Expected Content-Type " + MediaType.APPLICATION_JSON_UTF8 + ", was " + contentType + "."); 
     } 
     // handle potential exceptions from this as well 
     ObjectNode rootObject = objectMapper.readValue(inputMessage.getBody(), ObjectNode.class); 
     if (parameterType == String.class) { 
      JsonObjectProperty annotation = parameter.getParameterAnnotation(JsonObjectProperty.class); 
      return rootObject.get(annotation.name()).asText(); 
     } 
     // handle more 
     throw new HttpMessageNotReadableException("Could not read document. Parameter type " + parameterType + " not parseable."); 
    } 
} 

、最終的にハンドラメソッド

@RequestMapping(value = "/json-new", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) 
@ResponseBody 
public String handleJsonProperty(@JsonObjectProperty(name = "userId") String userId) { 
    String result = userId; 
    System.out.println(result); 
    return result; 
} 

を定義したいです。これを実行すると、そのJSONプロパティをパラメータに直接抽出できます。

+0

こんにちは、最初のおかげで多くのアドバイスをしています。あなたの答えを編集し、最初の部分だけを削除しました。**正確には**私がやったことです**私は自分の質問で尋ねたものと似ているから**やりたくないです。残りの部分は素晴らしいですし、私があなたのプロジェクトで実装を行うことができれば、私はSpringプロジェクトにそれをプッシュできることを願っています。 –

+0

@ usr-local-ΕΨΗΕΛΩΝPOJOがほしいと思っていませんでした。 –

+0

...マップではない、またはModelMap :-)これらの型は非常に一般的なので、コンパイル時に何が入っているのか分かりません。 –

0

いくつかのJSONインラインパーサー(XML Xpathに似ています)を使用して、JSON文字列を指定し、パーサーにString、List、Mapなどのサブ文書を取得するよう依頼することができます。例の1つはOGNLです。これは非常に強力なツールですが、これは唯一のものではなく、最も効率的ですが、成熟し安定したApache製品です。したがって、あなたのケースでは、JSON文字列をOGNLに供給し、プロパティ "userId"と "role"を別々の文字列として取得するように指示できます。 Apache OGNL page

+0

申し訳ありませんが、要点は可能な限り短い構文を使用することです。だから私はメソッドの引数**として値を得るために**必要があります** **、**または** Springのソースコードに掘り下げ、モジュールを開発して可能にし、おそらくSpringにプルリクエストを提出します。それは私の上司の要求です –

関連する問題