-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow reading/writing writerExcludingView()
/readerExcludingView()
(JsonView exclusion)
#456
Comments
Sounds like a reasonable idea to me. It seems there could be multiple ways to denote this. Another approach would instead add property in |
I was thinking it's better to have ObjectMapper.writerWithoutView() and ObjectMapper.readerWithoutView(). I like how @JSONVIEW designates some metadata around the property, and then I can later make a choice whether to exclude properties of a certain type from deserialization. However, if it's easier to do a @JSONVIEW annotation that excludes from some View, that will do the trick too. |
You can already specify 'writerWithView(null)' to remove use of active view. And specifying view value that does not match anything would allow having non-match. So how would this differ from existing possibilities? |
I'm sorry, I can see why "readerWithoutView" is confusing, and is actually a bad name (since "with"/"without" pairs are meant to control the same value). Right now is that the list of views is an "inclusion" views list, so *erWithView method means that the object should be serialized by only including the properties that match the supplied views (plus optionally any non-view-marked properties via DEFAULT_VIEW_INCLUSION). I'd like the ability to specify an exclusion list, where the behavior is to output non-view-marked properties, and properties belonging to any view other than the view specified. Perhaps a better method name is readerWithExcludedView. |
So you would want to inverse the logic of If so, this would probably be better done as a |
@cowtowncoder So you would write something like: mapper.writerWithView(A.class).with(EXCLUDE_VIEWS).write(); whereas @astral303 suggested: mapper.writerWithoutView(A.class).write() What about: mapper.writerExcludingView(A.class).write() |
@WaDelma agree, "excludingView" sounds better, and would be more concise than what I suggested. Internally it might make sense to pass a flag of some kind (to denote reversal), but that need not be exposed to user. |
+1 for this feature. It would be nice to have an exclude capability with However, I do prefer @astral303 approach of having this be defined in the object mapper config. The |
+1, This would have saved me quite a bit recently. |
One note on implementation: this would have to be "either or", in the sense that either active view is to be used for inclusion (include if property is included in view), or it is to be used for exclusion: it will not be possible to combine aspects. Second, internally this would need to be a combination of a So perhaps it really is better to only add Features to define inclusion/exclusion, without convenience methods, to keep things simple. I have not had any time to work on implementing this, or even follow through to see if it works, but I think it still makes sense and should be implementable with moderate changes, not major rewrite. |
Is there a workaround for this issue? |
+1 for this feature. Here is my use case for it. For security reasons, I would like to mark sensitive fields (e.g. passwords) in various domain objects with @JSONVIEW(Sensitive.class), and then configure the ObjectMapper used by my Jersey server to exclude all fields with the Sensitive view from both serialization and deserialization. That way our REST API would completely hide the sensitive fields from end users. Since there is currently no way to exclude views, I thought of a workaround. I tried making all other view classes being used in my project, except Sensitive.class, extend Public.class, and then configuring the ObjectMapper used by my Jackson server to include the Public view. Unfortunately, this did not work because there is a Jackson bug where subclass views do not work correctly (see #1146). |
+1 yes please I keep getting stuck when I try to use views because it would seem they are the simplest way to filter properties of my beans. However I'm always surprised that I can't actually use a view to exclude properties which is usually what I want. Excluding password, internalIds etc. In my latest use case I want to include an internal id for one small use case and exclude it for all others. I would have to add my @JSONVIEW(PublicView.class) in 100's of places. Not the to mention each time a developer forgets to add the annotation. Is there a workaround that folks are using? Filters seem unnecessarily complicated. |
@greenreign I do not understand the comment So maybe I am not understanding what you are saying here...? |
@cowtowncoder Right. I'm hoping I'm wrong but this requires that anytime I want to exclude password that I have to specify a view. Which means adding a lot of view wiring in my application. And debugging subtle problems when that wiring is missed. I would love to either
This would allow me to simply annotate the field I want excluded (most of the time) and override the view in the use cases where I'd like to actually include the field. |
@cowtowncoder That can work for the simplest of cases, but in my scenario I have a public a API and a private API. I want to present one version of the model to the world, and another version of the model to the database. Relying on unannotated fields as the default visibility is problematic for me. I've had to build a WithoutViewAnnotationInspector to allow for exclusion of desired properties: public class WithoutViewAnnotationInspector extends JacksonAnnotationIntrospector {
private Set<Class<? extends Annotation>> views
WithoutViewAnnotationInspector(Class<? extends Annotation> ... views) {
this.views = new HashSet<>(Arrays.asList(views)))
}
@Override
boolean hasIgnoreMarker(AnnotatedMember m) {
for (Class<? extends Annotation> view : this.views) {
if (m.getAnnotation(view) != null) return true;
}
return super.hasIgnoreMarker(m)
}
} Then I just a build an object mapper with that introspector: new ObjectMapper()
.setAnnotationIntrospector(new WithoutViewAnnotationInspector(ExcludeAnnotation.class)) |
writerExcludingView()
/readerExcludingView()
(JsonView exclusion)
Quick note: implementation of #507 -- ability to define default view for properties of a class -- might help with some use cases. Still planning to see if I find time to implement this for 2.9 (that is, evaluate how difficult it'd be to implement, and whether that's feasible within timeline). |
this would be great to add some day, defaults for all fields make for a decent workaround |
Often times it's convenient to mark some properties for a specific purpose (e.g. "historical" or "private"), and to simply use serializers that exclude that view. This is not possible right now, as you can only include views. Right now this means that all the other properties need to be tagged with a base/common view, which clutters up the code unnecessarily (or can be forgotten sometimes).
The text was updated successfully, but these errors were encountered: