- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图根据请求用户的角色有选择地隐藏响应中的某些字段。据我所知,来自 Jackson
的 JsonView
可能是正确的选择。
我需要能够显示所有字段,除非它们已标记有特定的访问级别。我为访问级别创建了以下结构:
(快速说明:我已将基本用户留在那里,但这并不重要)
public class View {
public static final Map<Role, Class> MAPPING = new HashMap<>();
static {
MAPPING.put(Role.ROLE_ADMIN, Admin.class);
MAPPING.put(Role.ROLE_USER, AuthenticatedUser.class);
}
public interface User {}
public interface AuthenticatedUser extends User {}
public interface Admin extends AuthenticatedUser {}
}
并按如下方式使用它们:
@Entity
public class SomeEntity {
@Id
@GeneratedValue
private Integer id;
private String baseInfo;
@JsonView(View.AuthenticatedUser.class)
private String userInfo;
@JsonView(View.Admin.class)
private String secretInfo;
...
}
(PS:我已经去掉了所有非必要的注释等)
现在,我预计根据访问级别,响应如下:
{
"id": 1,
"baseInfo": "Some basic info"
}
{
"id": 1,
"baseInfo": "Some basic info",
"userInfo": "Info only the user should be able to see"
}
{
"id": 1,
"baseInfo": "Some basic info",
"userInfo": "Info only the user should be able to see",
"secretInfo": "Info only the admin can see"
}
我使用了 this 中的代码将其集成到 spring security 和我自己的结构中的教程。
@RestControllerAdvice
class SecurityJsonViewControllerAdvice extends AbstractMappingJacksonResponseBodyAdvice {
@Override
protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType, MethodParameter returnType, ServerHttpRequest request, ServerHttpResponse response) {
if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().getAuthorities() != null) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
List<Role> foundRoles = authorities.stream()
.map(GrantedAuthority::getAuthority)
.map(Role::get).collect(Collectors.toList());
if (foundRoles.contains(null)) {
System.err.println("User has no auth. Setting no serialization view");
return;
}
List<Class> jsonViews = foundRoles.stream().map(View.MAPPING::get)
.collect(Collectors.toList());
if (jsonViews.size() == 1) {
System.err.println("Setting " + jsonViews.get(0) + " as serialization view");
bodyContainer.setSerializationView(jsonViews.get(0));
return;
}
throw new IllegalArgumentException("Ambiguous @JsonView declaration for roles "
+ authorities.stream()
.map(GrantedAuthority::getAuthority).collect(Collectors.joining(",")));
}
System.err.println("No auth found");
}
}
(请原谅糟糕的代码,我一直在尝试一切......)
此时,我希望结果与我上面所说的一样,但我继续获取所有字段,而不进行任何类型的过滤。任何类型的注释都不能避免字段被序列化。我知道我可以将默认值设置为排除除我注释的字段之外的所有字段,但这意味着注释所有字段并且项目相当大。
我对 JsonView 的最初假设是错误的,还是我在某个地方犯了错误?
提前致谢
最佳答案
感谢@second的评论,我已经能够解决这个问题了。事实证明我犯了两个小错误:
第一个更改是在 application.properties
文件中将 spring.jackson.mapper.default_view_inclusion
设置为 true
。通过这样做,Jackson 将默认包含所有属性,从而消除有效负载为空的问题
每当未经身份验证的用户尝试访问系统时,我们都需要将序列化 View 设置为基本用户。在我上面的帖子中,我有 User
View ,但我从未使用过它。将其设置为默认序列化 View (在上面的拦截器中)解决了问题,结果就是我上面所说的。
我上传了一个示例here 。它非常简单,但它显示了如何排除不同的字段。像这样使用:
http://localhost:8080/test
{
"id":1,
"baseInfo":"This is the base info"
}
http://localhost:8080/test?view=user
{
"id":1,
"baseInfo":"This is the base info",
"userInfo":"This is the user info"
}
http://localhost:8080/test?view=admin
{
"id":1,
"baseInfo":"This is the base info",
"userInfo": "This is the user info",
"secretInfo":"This is the secret info"
}
希望这有帮助!
关于java - 使用 JsonView 有选择地隐藏字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60956757/
我使用自定义反序列化器,但是当我调用objectMapper.writerWithView(Views.MyView.class)时,我没有得到预期的结果。 在调试的时候,我发现在方法中 public
我有包装 JPA 实体的 UI 对象,并且在该 UI 对象的构造函数中,我对某些属性进行了延迟加载。在同一个构造函数中,我需要知道 JsonView 当前处于事件状态,因此我不会延迟加载一些不需要的字
我需要使用@JsonView 在反序列化时抛出异常。 我的 POJO: public class Contact { @JsonView( ContactViews.Person.class
以下内容将仅包含具有 JsonView(View.MyView.class) 注释的字段: @JsonView(View.MyView.class) @RequestMapping(value = "
我无法使用@JsonView 执行这个简单的示例。我做错了什么? ${jackson-2-version} = 2.6.5 com.fasterxml.jackson.core ja
我正在尝试使用 @JsonView 注释从 Spring 中的对象反序列化多个字段。但是,我将注释添加到我的方法中,它没有反序列化指定的字段,而是返回一个空对象。 这是我的 POJO: @Entity
我正在尝试为我的嵌套实体使用 @JsonView 注释。更清楚地说,假设我们有 2 个实体,每个实体都有自己的 View 类。 public class JsonViewAddress {
我有以下测试设置: public class TestingPojo { public int getA() { return 1; } @JsonView(T
我试图根据请求用户的角色有选择地隐藏响应中的某些字段。据我所知,来自 Jackson 的 JsonView 可能是正确的选择。 我需要能够显示所有字段,除非它们已标记有特定的访问级别。我为访问级别创建
我的一个类有 3 个相同类型的属性。现在我正在尝试将其序列化为 JSON,但其中一个属性需要以不同的方式序列化 - 基本上这些属性之一是“内部”,我只需要它的 id,其余属性必须完全序列化。 到目前为
我将 Jackson JSON 1.9.12 与 SpringMVC 一起使用。我创建了一个带有 JSON 字段的 dto。我想要两个具有不同 JSON 字段的相同 dto 配置文件,因此我创建了两个
jackson 2.2.2 ObjectMapper mapper = new ObjectMapper(); mapper.getSerializationConfig().withView(Vie
如何在不在该 Java 对象的每个字段上指定 @JsonView 的情况下将 Java 对象的所有字段包含到 JSON 响应( View )中? 编辑:我需要在不使用另一个外部库的情况下实现这一点。
我有类似于这两个类的东西: public class User { @JsonView(UserView.IdOnly.class) int userID; String na
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
我正在开发一个 Spring boot(MVC、JPA)应用程序,它需要在不同的请求上返回不同的属性。我找到了 @JsonView 注释,它似乎有效。但是我需要用基本 View 来注释每个属性吗? 示
您好,我几乎没有相互嵌入的 UI 对象。示例 #1: class CarUI { public UserUI user; public UserUI agent; .... publi
我正在使用新的 CakePHP 2.1,并希望使用 JsonView 使我的 Controller 响应 JQuery 在客户端创建的 ajax 请求。但是,根据文档,这应该使用 JsonView 自
Spring 从 4.1 版本开始支持 @JsonView。 使用具有多个标识符的 @JsonView 注释 Spring Controller 的(使用 @RestController 注释)方法我
我有一个类包含另一个类的集合。 class A{ @JsonView(VerboseViewA.Minimal.class) String field1; @JsonView(VerboseVi
我是一名优秀的程序员,十分优秀!