我是Spring Boot的初学者,无法解决问题。我有一个实体类(Customer)和一个REST存储库(CustomerRepository)。该类包含一些我不希望由REST存储库公开的敏感字段。因此,我使用@JsonIgnore注释对这些字段进行了注释,如下所示:
package br.univali.sapi.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Customer
{
@Id
@GeneratedValue
private Long id = null;
private String login;
private String name;
@JsonIgnore
private String password;
@JsonIgnore
private String email;
public Customer()
{
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getLogin()
{
return login;
}
public void setLogin(String login)
{
this.login = login;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
}
一切正常,我的REST API返回了所需的结果。但是,当我向API发出POST请求以插入新实体时,我收到数据库错误:"column password can't be null", "column email can't be null"
。
密码和电子邮件将在POST请求中与其他参数一起发送到服务器,但似乎会被忽略。如果删除@JsonIgnore注释,则实体将保持正常。
我知道我可以使用投影隐藏这些字段。但是投影是URL中的可选参数。这样,有经验的用户就可以从请求URL中删除参数,并且无论如何都可以看到这些字段。
如果我可以隐式强制执行投射,那就可以解决问题,但这似乎不可能只使用Spring框架。我可以使用Apache URL重写来实现这一点,但维护很糟糕。
任何人都知道如何解决这个问题? 谢谢!
答案 0 :(得分:0)
我认为你对数据库级别没有空约束。基本上,当您在字段上@JsonIgnore
时,您只是不传递它,而数据库无法插入该值,这非常清楚。
所以我在这里看到的解决方案如下:
1)删除@JsonIgnore
注释,以便能够执行POST
次请求。
2)使用GET
时使用投影。您可以将Spring Data REST
配置为始终使用投影,但默认情况下Spring Data REST
始终会在单个资源上返回完整JSON
(在您使用电子邮件和密码的情况下),这是对我来说很奇怪。解决了这个问题我已经在another answer中写道,因为我也有同样的问题。只需使用ProjectingProcessor
并为所有投影使用一些默认名称。不要忘记使用config.getProjectionConfiguration().addProjection
方法在配置中添加投影。
3)避免第2步的唯一方法是禁止在GET
级别的单个资源上使用Spring Data REST
并使用自定义控制器。但我会采用步骤2中的解决方案来避免样板控制器。