ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-如何在spring-boot数据其余部分的POST json中传递@EmbeddedId

2019-11-08 08:04:36  阅读:210  来源: 互联网

标签:spring-boot spring-data-rest java


我已经使用Spring Boot Data REST构建了一个REST API.我正在使用EmbeddedId,并且还实现了BackendIdConverter.

以下是我的嵌入式课程

@Embeddable
public class EmployeeIdentity implements Serializable {
    @NotNull
    @Size(max = 20)
    private String employeeId;

    @NotNull
    @Size(max = 20)
    private String companyId;

    public EmployeeIdentity() {}

    public EmployeeIdentity(String employeeId, String companyId) {
        this.employeeId = employeeId;
        this.companyId = companyId;
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public String getCompanyId() {
        return companyId;
    }

    public void setCompanyId(String companyId) {
        this.companyId = companyId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        EmployeeIdentity that = (EmployeeIdentity) o;

        if (!employeeId.equals(that.employeeId)) return false;
        return companyId.equals(that.companyId);
    }

    @Override
    public int hashCode() {
        int result = employeeId.hashCode();
        result = 31 * result + companyId.hashCode();
        return result;
    }
}

这是我的员工模型

@Entity
@Table(name = "employees")
public class Employee {

    @EmbeddedId
    private EmployeeIdentity id;

    @NotNull
    @Size(max = 60)
    private String name;

    @NaturalId
    @NotNull
    @Email
    @Size(max = 60)
    private String email;

    @Size(max = 15)
    @Column(name = "phone_number", unique = true)
    private String phoneNumber;

    public Employee() {}

    public Employee(EmployeeIdentity id, String name, String email, String phoneNumber) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.phoneNumber = phoneNumber;
    }

    public EmployeeIdentity getId() {
        return id;
    }

    public void setId(EmployeeIdentity id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

并使用我的嵌入式ID而不是合格的类名正确生成资源链接

@Component
public class EmployeeIdentityIdConverter implements BackendIdConverter {

    @Override
    public Serializable fromRequestId(String id, Class<?> aClass) {
        String[] parts = id.split("_");
        return new EmployeeIdentity(parts[0], parts[1]);
    }

    @Override
    public String toRequestId(Serializable source, Class<?> aClass) {
        EmployeeIdentity id = (EmployeeIdentity) source;
        return String.format("%s_%s", id.getEmployeeId(), id.getCompanyId());
    }

    @Override
    public boolean supports(Class<?> type) {
        return Employee.class.equals(type);
    }
}

这是我的存储库代码

@RepositoryRestResource(collectionResourceRel = "employees", path = "employees")
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, EmployeeIdentity> {
}

这对于GET请求很好用,但是我需要能够POST.我注意到的第一件事是,当我使用json执行POST时

{
  "id": {
       "employeeId": "E-267", 
       "companyId": "D-432"
  },
  "name": "Spider Man", 
  "email": "spman@somedomain.com", 
  "phoneNumber": "+91-476253455"
}

这行不通. EmployeeIdentityIdConverter#fromRequestId抛出空指针异常,因为字符串参数为空.因此,我添加了一个null检查,并在id为null时返回默认的EmployeeIdentity.如本答案所述https://stackoverflow.com/a/41061029/4801462

修改后的EmployeeIdentityIdConverter#fromRequestId

@Override
public Serializable fromRequestId(String id, Class<?> aClass) {
    if (id == null) {
        return new EmployeeIdentity();
    }
    String[] parts = id.split("_");
    return new EmployeeIdentity(parts[0], parts[1]);
}

但这提出了另一个问题.由于使用了默认构造函数,而employeeId和companyId为null,因此我的hashCode和equals实现现在通过null指针异常进行.

为了解决这个问题,我给了employeeId和companyId默认值

**修改后的Employee#Employee()构造函数*

public Employee() {
    this.employeeId = "";
    this.companyId = "";
}

注意

我什至不确定我在上面做什么.我只是想解决发生的小问题.

顺便说一句,如果您认为这不起作用,那么您是对的.虽然我没有收到错误并且请求成功,但是没有得到我期望的行为.使用空的employeeId和companyId创建了一个新条目.

如何使POST到REST API的模型使用@EmbeddedId和spring boot数据休息?

解决方法:

这是另一种解决方案. (虽然还不完美.)

公开您的Employee类的ID:

@Configuration
  protected class MyRepositoryRestConfigurer implements RepositoryRestConfigurer {

   @Override
   public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
     config.exposeIdsFor(ThemeMessage.class);
   }
}

将以下行添加到转换器中(在POST请求期间,id为null):

@Override
public Serializable fromRequestId(String id, Class<?> aClass) {
    if(id==null) {
      return null;
    }
    String[] parts = id.split("_");
    return new EmployeeIdentity(parts[0], parts[1]);
}

以下POST请求将起作用:

{
  "id": {
       "employeeId": "E-267", 
       "companyId": "D-432"
  },
  "name": "Spider Man", 
  "email": "spman@somedomain.com", 
  "phoneNumber": "+91-476253455"
}

但是,id字段将在所有响应中公开.但这也许不是一个真正的问题,因为当您使用复合ID时,它通常意味着该ID不仅是抽象标识符,而且其各个部分都有有意义的内容,应该显示在实体主体中.

实际上,我也在考虑将这些行添加到我自己的代码中….::)

标签:spring-boot,spring-data-rest,java
来源: https://codeday.me/bug/20191108/2006490.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有