MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

@JsonView in Spring Boot:解锁 JSON 数据过滤的新姿势

2025-06-09 22:25 huorong 精选文章 1 ℃ 0 评论

Jackson是一个常用的Java JSON处理库,提供了丰富的注解来控制JSON与Java对象之间的序列化和反序列化,常用注解包括@JsonFormat、@JsonPropertyOrder、@JsonProperty、@JsonIgnore、@JsonInclude、@JsonTypeInfo、@JsonSubTypes、@JsonSerialize、@JsonDeserialize、@JsonView,用好这些注解将大大提高生产力。

以下是一个在Spring Boot中使用@JsonView的完整示例,展示如何根据不同的视图返回不同的字段:

1. 创建视图接口

// views/Views.java
package com.example.demo.views;

public class Views {
    public interface Public {}
    public interface Internal extends Public {}
}

2. 创建实体类

// model/User.java
package com.example.demo.model;

import com.example.demo.views.Views;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    @JsonView(Views.Public.class)
    private Long id;

    @JsonView(Views.Public.class)
    private String username;

    @JsonView(Views.Internal.class)
    private String email;

    private String password; // 未标记 @JsonView,默认不序列化
}

3. 创建控制器

// controller/UserController.java
package com.example.demo.controller;

import com.example.demo.model.User;
import com.example.demo.views.Views;
import com.fasterxml.jackson.annotation.JsonView;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/public/{id}")
    @JsonView(Views.Public.class)
    public User getPublicUser(@PathVariable Long id) {
        return createSampleUser(id);
    }

    @GetMapping("/internal/{id}")
    @JsonView(Views.Internal.class)
    public User getInternalUser(@PathVariable Long id) {
        return createSampleUser(id);
    }

    private User createSampleUser(Long id) {
        return new User(
            id,
            "john_doe",
            "john@example.com",
            "secret"
        );
    }
}

4. 配置Jackson

确保Jackson的视图功能被启用(通常Spring Boot自动配置已包含):

// config/JacksonConfig.java (可选)
package com.example.demo.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

@Configuration
public class JacksonConfig {

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        ObjectMapper mapper = new ObjectMapper();
        // 启用默认视图(如果需要)
        // mapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);
        return new MappingJackson2HttpMessageConverter(mapper);
    }
}

5. 测试API

启动应用后,访问以下端点:

公共视图(Public)

GET http://localhost:8080/users/public/1

响应

{
  "id": 1,
  "username": "john_doe"
}

内部视图(Internal)

GET http://localhost:8080/users/internal/1

响应

{
  "id": 1,
  "username": "john_doe",
  "email": "john@example.com"
}

关键说明

  1. 视图继承
    • Internal 视图继承自 Public,因此包含 Public 的所有字段。
  1. 控制器方法
    • 使用 @JsonView(Views.Public.class) 注解控制返回字段。
  1. 字段控制
    • password 字段未标记 @JsonView,始终不会被序列化。
  1. 全局配置
    • 通过 MapperFeature.DEFAULT_VIEW_INCLUSION 可控制默认视图行为。

进阶用法

在Service层使用视图

@Service
public class UserService {
    @JsonView(Views.Public.class)
    public User getPublicUser(Long id) {
        // ...
    }
}

动态选择视图

@GetMapping("/{id}")
public ResponseEntity<?> getUser(@PathVariable Long id, @RequestParam(required = false) boolean internal) {
    User user = userService.getUser(id);
    if (internal) {
        return ResponseEntity.ok()
            .body(objectMapper.writerWithView(Views.Internal.class).writeValueAsString(user));
    }
    return ResponseEntity.ok()
        .body(objectMapper.writerWithView(Views.Public.class).writeValueAsString(user));
}

依赖配置

确保 spring-boot-starter-web 已添加到 pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

通过这种方式,你可以灵活控制API返回的字段,实现数据的差异化展示。

Tags:java jsonpath

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言