@JsonView
を使用しない場合は、@JsonFilter
と考えることができます。 SimpleBeanPropertyFilter
を拡張し、ユーザーの役割に応じて直列化を制御することができ最初の必要性:
public class RoleBasedPropertyFilter extends SimpleBeanPropertyFilter {
private String allowedRole;
public RoleBasedPropertyFilter(String allowedRole) {
this.allowedRole = allowedRole;
}
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen,
SerializerProvider provider,
PropertyWriter writer) throws Exception {
PermitAll permitAll = writer.getAnnotation(PermitAll.class);
if (permitAll != null) {
serializeAsField(pojo, jgen, provider, writer);
return;
}
DenyAll denyAll = writer.getAnnotation(DenyAll.class);
if (denyAll != null) {
writer.serializeAsOmittedField(pojo, jgen, provider);
return;
}
RolesAllowed rolesAllowed = writer.getAnnotation(RolesAllowed.class);
if (rolesAllowed != null) {
if (!Arrays.asList(rolesAllowed.value()).contains(allowedRole)) {
writer.serializeAsOmittedField(pojo, jgen, provider);
return;
}
}
// If no annotation is provided, the property will be serialized
serializeAsField(pojo, jgen, provider, writer);
}
}
@JsonFilter("roleBasedPropertyFilter")
でそれに注釈を付け、特定のBeanにフィルタを適用するには:
@JsonFilter("roleBasedPropertyFilter")
public class User {
private String firstName;
private String lastName;
private String email;
private String password;
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@RolesAllowed({"ADMIN"})
public String getEmail() {
return email;
}
@DenyAll
public String getPassword() {
return password;
}
// Other getters and setters
}
その後、あなたにあなたのフィルタを登録しますObjectMapper
ためContextResolver
:
String currentUserRole = // Get role from the current user
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("roleBasedPropertyFilter",
new RoleBasedPropertyFilter(currentUserRole));
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
あなたのフィルタが「グローバル」にしたい、つまり、すべてのBeanに適用する場合、あなたはミックスインクラスを作成し、@JsonFilter("roleBasedPropertyFilter")
でそれに注釈を付けることができます。
@JsonFilter("roleBasedPropertyFilter")
public class RoleBasedPropertyFilterMixIn {
}
そして、ミックスインクラスをバインドします〜Object
:
mapper.addMixIn(Object.class, RoleBasedPropertyFilterMixIn.class);
最新のバージョンのジャクソンとRESTEasyを使用する必要があります。あなたは言った:_モデルは、大規模なデータセットのすべての単一のプロパティに正しいシリアル化をマークするのに時間がかかりすぎるほど大きいです_そうですか、プロパティをフィルタリングするためにどの基準を適用しますか? –
この解決策は、長い間廃止され廃止されたメソッド 'ObjectMapper :: getSerializationConfig :: setSerializationView'を参照しています。私は同じように見えたが、結果がなかった 'withView'メソッドを試してみました。質問で言われているように、ユーザーはそのフィールドにアクセスするための特定のアクセス許可を持っていなければなりません。例えば。 ADMIN権限を持つユーザーはアクセスできます。それ以外の場合はアクセスできません。 IMHOを使用すると、コードを読みやすくしてユースケースを区別しやすくなります。 – Luca
ロール固有のシリアル化を実行することを理解しています。私が尋ねるのは、ビューを使用したくない場合(各Beanの各プロパティに注釈を付ける)、どの基準を使用して直列化されるプロパティを選択するのですか?一つの選択肢は、名前でプロパティをフィルタリングすることです(例えば、 'SimpleBeanPropertyFilter'を使います)。次に、 'ContextResolver'では、ビューを設定する代わりにフィルターを設定します。 –