要するに、私のエンティティの1つに GeometryCollection があり、これが「getBoundary」を呼び出すと例外をスローします(この理由は別の本です。
特定のゲッターを含めないようにジャクソンに伝える方法はありますか?コードを所有/制御するときに@JacksonIgnoreを使用できることを知っています。しかし、これはそうではありません。ジャクソンは、親オブジェクトの継続的なシリアル化を通じてこのポイントに到達しなくなります。 jacksonのドキュメントにフィルタリングオプションがありました。それはもっともらしい解決策ですか?
ありがとう!
Jackson Mixins を使用できます。例えば:
class YourClass {
public int ignoreThis() { return 0; }
}
このMixinで
abstract class MixIn {
@JsonIgnore abstract int ignoreThis(); // we don't need it!
}
これとともに:
objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class);
編集:
Jackson 2.5+のコメントのおかげで、APIが変更されました。objectMapper.addMixIn(Class<?> target, Class<?> mixinSource)
で呼び出す必要があります
もう1つの可能性は、不明なプロパティをすべて無視する場合、マッパーを次のように構成できることです。
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Javaクラスを使用
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
注釈を使用
@JsonIgnoreProperties(ignoreUnknown=true)
注釈ベースのアプローチの方が優れています。しかし、時には手動操作が必要です。この目的のためにwithoutObjectWriterのメソッドを使用できます。
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ObjectWriter writer = mapper.writer().withoutAttribute("property1").withoutAttribute("property2");
String jsonText = writer.writeValueAsString(sourceObject);
既に述べたように、ここでミックスインアノテーションは非常にうまく機能します。プロパティごとの@JsonIgnoreを超える別の可能性は、含めるべきではない型がある場合(つまり、GeometryCollectionプロパティのすべてのインスタンスを無視する必要がある場合)に@JsonIgnoreTypeを使用することです。次に、タイプを制御する場合は直接追加するか、次のようにミックスインを使用します。
@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule
これは、すべてが単一の 'IgnoredType getContext()'アクセサーを持つクラスが多数ある場合に便利です(多くのフレームワークの場合)
私は同様の問題を抱えていましたが、それはHibernateの双方向の関係に関連していました。私が扱っていた見解に応じて、関係の一方を示し、プログラムで他方を無視したかった。それができない場合、厄介なStackOverflowException
sになります。たとえば、これらのオブジェクトがあった場合
public class A{
Long id;
String name;
List<B> children;
}
public class B{
Long id;
A parent;
}
Aを見ている場合はBのparent
フィールドをプログラムで無視し、Bを見ている場合はAのchildren
フィールドを無視します。
私はこれを行うためにミックスインを使い始めましたが、それはすぐに恐ろしくなります。データをフォーマットするためだけに存在する非常に多くの役に立たないクラスがあります。これをよりクリーンな方法で処理するために、独自のシリアライザーを作成することになりました: https://github.com/monitorjbl/json-view 。
無視するフィールドをプログラムで指定できます。
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);
List<A> list = getListOfA();
String json = mapper.writeValueAsString(JsonView.with(list)
.onClass(B.class, match()
.exclude("parent")));
また、ワイルドカードマッチャーを使用して、非常に単純化されたビューを簡単に指定できます。
String json = mapper.writeValueAsString(JsonView.with(list)
.onClass(A.class, match()
.exclude("*")
.include("id", "name")));
私の元のケースでは、このような単純なビューの必要性は、親/子に関する最低限の情報を表示することでしたが、ロールベースのセキュリティにも役立ちました。オブジェクトに関するより少ない情報を返すために必要なオブジェクトの特権の少ないビュー。
これらはすべてシリアライザーからのものですが、アプリではSpring MVCを使用していました。これらのケースを適切に処理するために、既存のSpringコントローラークラスにドロップできる統合を作成しました。
@Controller
public class JsonController {
private JsonResult json = JsonResult.instance();
@Autowired
private TestObjectService service;
@RequestMapping(method = RequestMethod.GET, value = "/bean")
@ResponseBody
public List<TestObject> getTestObject() {
List<TestObject> list = service.list();
return json.use(JsonView.with(list)
.onClass(TestObject.class, Match.match()
.exclude("int1")
.include("ignoredDirect")))
.returnValue();
}
}
どちらもMaven Centralで利用できます。これが他の誰かの助けになることを願っています。これはジャクソンにとって特にい問題であり、私の場合には良い解決策がありませんでした。
クラスの特定のプロパティを常に除外する場合は、setMixInResolver
メソッドを使用できます。
@JsonIgnoreProperties({"id", "index", "version"})
abstract class MixIn {
}
mapper.setMixInResolver(new ClassIntrospector.MixInResolver(){
@Override
public Class<?> findMixInClassFor(Class<?> cls) {
return MixIn.class;
}
@Override
public ClassIntrospector.MixInResolver copy() {
return this;
}
});
ここでもう1つの良い点は、@JsonFilter
を使用することです。詳細はこちら http://wiki.fasterxml.com/JacksonFeatureJsonFilter