json-view
json-view copied to clipboard
Exceptions at usage
Hi,
sorry for the issue, but i saw no way to contact you directly.
i have a controller-method, that returns a single user of the system. I have tried to hide the company of the user if the caller is no superadmin.
JsonView.with(user).onClass(User.class, match().exclude("company"))
I registered your JsonView to my CustomObjectMapper as well, but the code above throws recursively exceptions.
In the README you are always using lists. Is your library not possible on single objects?
Second question: How do you return a ResponseBody with a void function? Is this the problem in my case? I return the user after i tried to filter the company attribute.
Thanks, Tobias
It's fine to make an issue to ask questions! Can you add an example test case? I'm not really sure what's going on in your environment, that should work just fine.
Thanks for your fast response!
I have an UserController which basically returns a user. According to the role of the calling user, several properties should not be returned to the client.
I followed your README file instructions for Spring Integration (added dependency and Bean).
@RequestMapping(value = "/{userId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public @Valid @ResponseBody ResultWrapper<UserDataDTO> getUser(@PathVariable("userId") final String userId,
@AuthenticationPrincipal final UserAuthentication userDetails)
UserDataDTO initiator = userService.getOwnUserByEmail(userDetails.getName());
UserDataDTO userDataDTO = UserService.tryGetUserDataByUserId(initiator, UUID.fromString(userId));
ResultWrapper<UserDataDTO> wrapper = null;
if (initiator.getRole() != Role.SuperAdmin) {
wrapper = json.use(JsonView.with(userDataDTO).onClass(UserDataDTO.class, Match.match().exclude("company")));
} else {
wrapper = json.use(JsonView.with(userDataDTO));
}
return wrapper;
}
But if i execute the code i only get Stackoverflow here:
at com.monitorjbl.json.JsonViewSerializer$JsonWriter.write(JsonViewSerializer.java:347) ~[json-view-0.10.jar:na]
at com.monitorjbl.json.JsonViewSerializer$JsonWriter.writeList(JsonViewSerializer.java:154) ~[json-view-0.10.jar:na]
I get many log entries like that. Seems like this happens in a recursion (see exception.txt) .
You should return your object, not the ResultWrapper
. You can do this:
@RequestMapping(value = "/{userId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public @Valid @ResponseBody UserDataDTO getUser(@PathVariable("userId") final String userId,
@AuthenticationPrincipal final UserAuthentication userDetails){
UserDataDTO initiator = userService.getOwnUserByEmail(userDetails.getName());
UserDataDTO userDataDTO = UserService.tryGetUserDataByUserId(initiator, UUID.fromString(userId));
if (initiator.getRole() != Role.SuperAdmin) {
return json.use(JsonView.with(userDataDTO).onClass(UserDataDTO.class, Match.match().exclude("company"))).returnValue();
} else {
return json.use(JsonView.with(userDataDTO)).returnValue();
}
}
The returnValue()
method simply returns the object so you can easily use this library if your methods have return types. Alternatively, you can not return anything. The Spring integration doesn't actually use the return value directly, so it's not required:
@RequestMapping(value = "/{userId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public @Valid @ResponseBody void getUser(@PathVariable("userId") final String userId,
@AuthenticationPrincipal final UserAuthentication userDetails){
UserDataDTO initiator = userService.getOwnUserByEmail(userDetails.getName());
UserDataDTO userDataDTO = UserService.tryGetUserDataByUserId(initiator, UUID.fromString(userId));
if (initiator.getRole() != Role.SuperAdmin) {
json.use(JsonView.with(userDataDTO).onClass(UserDataDTO.class, Match.match().exclude("company")));
} else {
json.use(JsonView.with(userDataDTO));
}
}