首页 > 解决方案 > 与 HATEOAS 集成正在从 Springboot REST API 中的 JSON 响应中删除 id 字段

问题描述

我在我的 Springboot REST 项目中使用 HATEOAS。我遇到了一个奇怪的问题!'id' 字段没有响应。Entity 类的所有其他字段都正确出现。这只发生在我使用 HATEOAS 链接返回 EntityModel 作为响应时。如果我返回没有 HATEOAS 链接的 ResponseEntity,则响应中存在 id 字段。

控制器类

@RestController
@RequestMapping("/employees")
@RequiredArgsConstructor
public class EmployeeController {

    private final EmployeeService employeeService;

    @GetMapping("/all")
    public ResponseEntity<?> fetchEmployees(){
        List<Employee> employees = employeeService.getAllEmployees();
        return ResponseEntity.ok(employees);
    }

    // With HATEOAS links. -- does not return id in response

    @GetMapping("/one/{id}")
    public EntityModel<Employee> fetchEmployee(@PathVariable int id){
        Employee employee = employeeService.getEmployee(id);

        return EntityModel.of(employee,
                linkTo(methodOn(EmployeeController.class).fetchEmployee(id)).withSelfRel(),
              linkTo(methodOn(EmployeeController.class).fetchEmployees()).withRel("employees"));
   
    }

   //without HATEOAS links.  -- returns id in response
    @GetMapping("/single/{id}")
    public ResponseEntity<?> fetchSingleEmployee(@PathVariable int id){
        Employee employee = employeeService.getEmployee(id);
        return ResponseEntity.ok(employee);
    }

员工(实体)

@Entity
@Setter @Getter
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private int age;
    private int salary;
    private LocalDateTime joiningDate;
    private boolean active;

    public Employee(){

    }

    public Employee(int id, String name, int age, int salary, LocalDateTime joiningDate, boolean active) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.joiningDate = joiningDate;
        this.active = active;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return id == employee.id && age == employee.age && salary == employee.salary && active == employee.active && Objects.equals(name, employee.name) && Objects.equals(joiningDate, employee.joiningDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age, salary, joiningDate, active);
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name +
                ", age=" + age +
                ", salary=" + salary +
                ", joiningDate=" + joiningDate +
                ", active=" + active +
                '}';
    }
}

EmployeeService(服务)

@Service
@RequiredArgsConstructor
public class EmployeeService {
    private final EmployeeRepository employeeRepository;

    public Employee getEmployee(int id){
        Optional<Employee> optionalEmployee = employeeRepository.findById(id);
        return optionalEmployee.orElseThrow(() -> new EmployeeNotFoundException(id));
    }

    public List<Employee> getAllEmployees(){
        List<Employee> empList = employeeRepository.findAll();
        return Optional.of(empList).orElseThrow(EmployeeNotFoundException::new);
    }
}

EmployeeRepository(存储库)

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}

当我调用未配置 HATEOAS 链接的 GET 端点时,它工作正常并返回所有字段作为响应,包括“id”。

ajaysingh@mac ~ % curl -X 'GET' \
  'http://localhost:8080/employees/single/1' \
  -H 'accept: */*'
{"id":1,"name":"Euler","age":32,"salary":34000,"joiningDate":"2016-06-22T19:10:25","active":true}%                              
ajaysingh@mac ~ % 

但是当我使用 hatoas 链接调用 GET 端点时,它不会在响应中返回“id”。其余所有字段均正确显示。'id' 字段未显示。

ajaysingh@mac ~ % curl -X 'GET' \
  'http://localhost:8080/employees/one/1' \
  -H 'accept: */*'
{
  "name" : "Euler",
  "age" : 32,
  "salary" : 34000,
  "joiningDate" : "2016-06-22T19:10:25",
  "active" : true,
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/employees/one/1"
    },
    "employees" : {
      "href" : "http://localhost:8080/employees/all"
    }
  }
}%                                                                                                                              ajaysingh@mac ~ % 

我也尝试过调试,发现员工对象包含 id,直到它被传递给 EntityModel。只有在 EntityModel 处理它之后, id 才会被删除。

员工对象包含 id

标签: spring-boothateoas

解决方案


推荐阅读