2017-05-06 11 views
-1

私はREST環境に新しいです、私は非常に単純なBeanがResquestBody JSONの一部としてキーまたは重複キー値が重複していると、REST環境で不正な要求が発生しますか?

public class Operations 
{ 
String operationName, 
int operationPriority, 
boolean isOperationParallel, 
boolean expirationPolicy 
} 

ので、JSONはにサーバー側で

'{ 
    "operationName": "NewOperation", 
    "operationPriority": 2, 
    "isOperationParallel": false, 
    "expirationPolicy": 30 
}' 

だろうオペレーション豆にリクエストを作成するには、次のプロパティでの操作の呼び出されていJSONを私が使用しているオペレーションBeanにマップします。デフォルトでは、重複キーが与えられ、最後のキー値でオーバーライドされます。例えば、operationNameNewOperationTwo

です。
'{ 
     "operationName": "NewOperation", 
     "operationName": "NewOperationTwo", 
     "operationPriority": 2, 
     "isOperationParallel": false, 
     "expirationPolicy": 30 
    }' 

今私はHTTPステータスレスポンスとして400 BAD_REQUESTになるはずであることを私たちのQAから聞きました。「Dog」のような未知のプロパティの場合は、400応答にもつながるはずです:「Barks」もリクエストボディの一部として渡され、デフォルトではJacksonによっても無視されます。

私の要点は、要求を解析して重複している不明なプロパティを見つけることで400を送信するのは大丈夫ですが、このオーバーヘッドが必要ですか?なぜなら、それが委任であれば、Springはデフォルトで応答BAD_REQUESTを返すはずだからです。

標準REST APIレスポンスがリクエスト本体の重複したキーと未知のキーのためにどのようなものになるのか、BAD_REQUESTをレスポンスとして返さないとどうなるでしょうか?

答えて

0

Jsonでは、重複して不明なKeyに対して標準REST API応答が定義されていません。しかし、またはmulitpart/from-dataのようなContent-Typeを使用している場合、要求パラメータ名は一意である必要があります。これはJSONには適用されません。各アプリケーションでjsonのfromatがどのようなものになるかを判断することはできません。

したがって、このような状況をどのように処理するかを決定するのは、組織化のビジネス要件までです。そして、この制約をアプリケーションに実装するのはソフトウェア開発者の役割です。

あなたのQAエンジニア と不明なフィールドの重複のために400のステータスを送り返す必要があるとします。これは、JSONリクエスト/レスポンス構造が固定されている場合は、その

更新

のように行わなければなりません。次に、JAXBを使用して、通常のPOJOに対して値オブジェクト(VO)などのパターン・オブジェクトを設計して、着信データと発信データを処理できます。 JAXBを使用してJsonをJavaオブジェクトにバインドし、その後でフレームワークで提供される評価機能を使用できます。あなたがそれなしで置くことになるかなりの労力を軽減します。あなたがジャージーを使用している場合

JAXB support in jersey

bean validation support in Jersey

+0

これはまさに私が言っていることですが、 'application/x-www-form-urlencoded'や' mulitpart/from data 'のように必須ではありません。フォームデータとレスポンスボディー、またなぜオーバーヘッドを取るのか、結果はどうなるでしょうか?今は小さなJSONの場合は、非常に大きな入れ子になった複雑なJSONの場合はどれくらいの処理が必要ですか? –

+0

詳細については、 –

+0

の更新プログラムを参照してください。しかし、より簡単に見つけられます。詳細については、アップデート2を参照してください。 –

0
私が作成した

ソリューションの後半の応答のため申し訳ありませんが、これは私が前方に行って何で、

より多くのアイデアを持っている休閑リンクを介して行きますjacksonのためのカスタムHttpMessageConverter、最初は私はMappingJackson2HttpMessageConverter & MappingJacksonHttpMessageConverter の間で混乱していましたが、MappingJackson2HttpMessageConverterでJacksonを読んで読んでしまいました。したがって、以下

は、基本的には

read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) 
        throws IOException, HttpMessageNotReadableException 

リクエスト本体からメッセージを含み、ObjectMapper

にそれを渡す方法であった3つのメソッドをオーバーライドする必要があり、カスタムメッセージコンバータであります設定class.Belowがコード

@Override 
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
    CustomMappingJackson2HttpMessageConverter jsonConverter = 
        CustomMappingJackson2HttpMessageConverter(); 
    List<MediaType> mediaTypeList = new ArrayList<MediaType>(); 
    mediaTypeList.add(MediaType.APPLICATION_JSON); 
    jsonConverter.setSupportedMediaTypes(mediaTypeList); 
    converters.add(jsonConverter); 
    super.configureMessageConverters(converters); 
} 
ですcontext.In
public class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter { 

    private static final Logger logger = 

    private ObjectMapper objectMapper; 

    private boolean prefixJson = false; 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#setPrefixJson(boolean) 
    */ 
    @Override 
    public void setPrefixJson(boolean prefixJson) { 
     this.prefixJson = prefixJson; 
     super.setPrefixJson(prefixJson); 
    } 


    /* 
    * (non-Javadoc) 
    * 
    * @see org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#read(java.lang.reflect.Type, 
    * java.lang.Class, org.springframework.http.HttpInputMessage) 
    */ 
    @Override 
    public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) 
        throws IOException, HttpMessageNotReadableException { 
     objectMapper = new ObjectMapper(); 
     objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); 
     objectMapper.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false); 
     objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true); 
     objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, true); 
     objectMapper.configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true); 

     InputStream istream = inputMessage.getBody(); 
     String responseString = IOUtils.toString(istream); 
     try { 
      return objectMapper.readValue(responseString, OperatorTokenDefinition.class); 
     } catch (UnrecognizedPropertyException ex) { 
      throw new YourCustomExceptionClass(); 
     } catch (InvalidFormatException ex) { 
      throw new YourCustomExceptionClass(); 
     } catch (IgnoredPropertyException ex) { 
      throw new YourCustomExceptionClass(); 
     } catch (JsonMappingException ex) { 
      throw new YourCustomExceptionClass(); 
     } catch (JsonParseException ex) { 
      logger.error("Could not read JSON JsonParseException:{}", ex); 
      throw new YourCustomExceptionClass(); 
     } 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#supports(java.lang.Class) 
    */ 
    @Override 
    protected boolean supports(Class<?> arg0) { 
     return true; 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal(java.lang.Object, 
    * org.springframework.http.HttpOutputMessage) 
    */ 
    @Override 
    protected void writeInternal(Object arg0, HttpOutputMessage outputMessage) 
        throws IOException, HttpMessageNotWritableException { 
     objectMapper = new ObjectMapper(); 
     String json = this.objectMapper.writeValueAsString(arg0); 
     outputMessage.getBody().write(json.getBytes(Charset.defaultCharset())); 
    } 

    /** 
    * @return 
    */ 
    private ResourceBundleMessageSource messageSource() { 
     ResourceBundleMessageSource source = new ResourceBundleMessageSource(); 
     source.setBasename("messages"); 
     source.setUseCodeAsDefaultMessage(true); 
     return source; 
    } 
} 

は今だけ、私たちは春とカスタムMessageConverterを登録する必要があります

関連する問題