2017-08-30 137 views
0

我使用Spring Rest 4(spring-boot-starter-data-jpa,spring-boot-starter-data-rest,spring- boot-starter-security)并使用CrudRepository访问我的组织数据。 GET和PUT工作正常,但我的POST不断从浏览器中看到一个空对象。Spring CrudRepository save()不POST,因为它认为它的参数为空

以下是报告的错误的删节版:

2017-08-30 06:27:00.049 ERROR 1312 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [com.logicaltiger.exchangeboard.model.Org] during persist time for groups [javax.validation.groups.Default, ] 
List of constraint violations:[ 
    ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=userId, rootBeanClass=class com.logicaltiger.exchangeboard.model.Org, messageTemplate='{javax.validation.constraints.NotNull.message}'} 
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=address1, rootBeanClass=class com.logicaltiger.exchangeboard.model.Org, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'} 
    ... 
] with root cause 

javax.validation.ConstraintViolationException: Validation failed for classes [com.logicaltiger.exchangeboard.model.Org] during persist time for groups [javax.validation.groups.Default, ] 
List of constraint violations:[ 
    ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=userId, rootBeanClass=class com.logicaltiger.exchangeboard.model.Org, messageTemplate='{javax.validation.constraints.NotNull.message}'} 
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=address1, rootBeanClass=class com.logicaltiger.exchangeboard.model.Org, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'} 
    ... 
] 

这里是正在从浏览器(JavaScript)的发送的内容的删节版:

$("#OrgPostBtn").click(function() { 
    $.ajax({ 
     url: "/org", 
     type: "POST", 
     data: JSON.stringify({ provider: true, name: 'Org NEW', address1: 'Address 24', [SNIP], userId: 2 }), 
     contentType: "application/json; charset=utf-8", 
     headers: createAuthorizationTokenHeader(), 
     dataType: "json", 
     success: function (data, textStatus, jqXHR) { 
      console.log("success: data: " + data + ", textStatus: " + textStatus + ", jqXHR: " + jqXHR); 
     }, 
     error: function (jqXHR, textStatus, errorThrown) { 
      console.log("error: jqXHR: " + jqXHR + ", textStatus: " + textStatus); 
     } 
    }); 
}); 

这里是仓库:

@RepositoryRestResource(path="org") 
public interface OrgRepository extends CrudRepository<Org, Long> { 

    @Override 
    @PostAuthorize("returnObject.userId == principal.id || hasRole('ROLE_ADMIN')") 
    public Org findOne(@Param("id") Long id); 

    @Override 
    @PostFilter("filterObject.user_id == principal.id || hasRole('ROLE_ADMIN')") 
    public Iterable<Org> findAll(); 

} 

这里是Org的删节版:

@Entity 
@Table(name="org") 
public class Org implements Serializable { 
    private static final long serialVersionUID = -2808050088097500043L; 

    @Id 
    @Column(name="id") 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id = Utilities.INVALID_ID; 

    @Column(name="provider", nullable=false) 
    @NotNull 
    private boolean provider; 

    @Column(name="name", length=100, nullable=false) 
    @NotEmpty 
    @Size(max=100) 
    private String name; 

    @Column(name="address1", length=50, nullable=false) 
    @NotEmpty 
    @Size(max=50) 
    private String address1; 

    @Column(name="user_id", nullable=false) 
    @NotNull 
    private Long userId; 

    [SNIP] 
} 

因此,我没有对PUT或POST进行特殊处理,并且PUT处理正常。但是我的POST数据没有被识别。

其实,这是我原来的问题的降级版本,这@PreAuthorize()或@PostAuthorize从看空#entity:

@Override 
@SuppressWarnings("unchecked") 
@PreAuthorize("#entity.userId == principal.id || hasRole('ROLE_ADMIN')") 
public Org save(@Param("entity") Org entity); 

所以...我注释保存参数( @Param),或者我根本没有overriden save()。该程序认为我试图POST一个空对象。

如何使用CrudRepository修复此问题?

在此先感谢,

杰罗姆。

+0

userId作为字符串发布 - 您需要确保将其转换为使用转换器的较长时间。检查日志以确认。修正是使用这种类型的转换器 - https://stackoverflow.com/questions/22965178/automatically-convert-a-parameter-with-spring-data-jpa – farrellmr

+0

我有麻烦与你的断言。在findOne()@PostAuthorize(“returnObject.userId == principal.id || hasRole('ROLE_ADMIN')”)正常工作。但看到我的“答案”。 –

回答

0

我已经想出了如何为PUT和POST配置此存储库。在授权后使用returnObject,就像这样:

@RepositoryRestResource(path="org") 
public interface OrgRepository extends CrudRepository<Org, Long> { 

    @Override 
    @PostAuthorize("returnObject.userId == principal.id || hasRole('ROLE_ADMIN')") 
    public Org findOne(@Param("id") Long id); 

    @Override 
    @PostFilter("filterObject.userId == principal.id || hasRole('ROLE_ADMIN')") 
    public Iterable<Org> findAll(); 

    @Override 
    @SuppressWarnings("unchecked") 
    @PostAuthorize("reutrnObject.userId == principal.id || hasRole('ROLE_ADMIN')") 

} 

有了这个我越来越: 一个普通用户只能将他/她自己的组织记录(用户ID匹配)。 一个普通的用户可以POST任何东西。 管理员可以PUT或POST任何东西。

相关问题