私はJAX-RSに慣れており、Spring MVCを使用してリクエストを送信し、応答を操作するとき、つまりテスト内のクライアント側で同様の快適さを実現したいと考えています。
サーバー(コントローラー)側では、自動変換に非常に満足しています。つまり、オブジェクトインスタンスを返し、結果のHTTP応答にJSONをクライアントに送信するだけで十分です。
変換の手動プロセスを回避する方法を教えてください objectInstance
に jsonString
またはその逆はこれらのスニペットですか?可能であれば、コンテンツタイプの手動設定もスキップしたいと思います。
String jsonStringRequest = objectMapper.writeValueAsString(objectInstance);
ResultActions resultActions = mockMvc.perform(post(PATH)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonStringRequest)
)
String jsonStringResponse = resultActions.andReturn().getResponse().getContentAsString();
Some objectInstanceResponse = objectMapper.readValue(jsonStringResponse, Some.class);
比較のために、JAX-RSクライアントAPIを使用すると、を使用してオブジェクトを簡単に送信できます。 request.post(Entity.entity(objectInstance, MediaType.APPLICATION_JSON_TYPE)
を使用して応答を読みます response.readEntity(Some.class);
回答:
回答№1は0応答オブジェクトがたくさんある場合は、いくつかの汎用JsonToObjectマッパーファクトリを作成します。次に、ジェネリック応答からオブジェクトタイプを検出し(すべての応答オブジェクトは同じジェネリッククラスから継承します)、不正なマッピング試行から適切に応答/ログを記録するために使用できます。
手元にコード例はありませんが、疑似コードとして:
public abstract GenericResponse {
public String responseClassName = null;
// get/set
}
サーバーコードで、実際の応答オブジェクトの名前をこのクラスに追加します。
JsonToObjectファクトリ
public ConverterFactory<T> {
private T objectType;
public ConverterFactory(T type) {
objectType = type;
}
public T convert(String jsonString) {
// Type check
GenericResponse genResp = mapper.readValue(result.getResponse().getContentAsString(),
GenericResponse.class);
if (objectType.getClass().getSimpleName().equals(genResp.getResponseClassName())) {
// ObjectMapper code
return mapper.readValue(result.getResponse().getContentAsString(),
objectType.class);
} else {
// Error handling
}
}
}
これを拡張してアノテーションとともに使用し、応答でより多くの自動化マジックを実行できると思います。 (BeanPostProcessorでチェックを開始します)
@Component
public class AnnotationWorker implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(final Object bean, String name) throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(), field -> {
// make the field accessible if defined private
ReflectionUtils.makeAccessible(field);
if (field.getAnnotation(MyAnnotation.class) != null) {
field.set(bean, log);
}
});
return bean;
}
}
上記のコードスニペットは私の現在のプロジェクトからコピーされ、フィールドに挿入されます。メソッドで機能するように変更する必要があります。たとえば、必要な場所で使用できます。
これをすべて実装するのは難しいかもしれませんし、必ずしもうまくいくとは言えませんが、少しの教育的な仕事を気にしないのであれば、試してみることができます。