ITPub博客

首页 > 数据库 > 数据库开发技术 > Spring-Data-REST修改默认配置

Spring-Data-REST修改默认配置

原创 数据库开发技术 作者:HelloTech技术派 时间:2017-12-22 21:50:00 0 删除 编辑

背景

在上一篇中除去配置类和实体类,写了两行代码,就实现了RESTful风格的接口,但在实际使用时,还需要一些额外的处理,比如在返回的数据中,password这类敏感字段是不应该返回的;删除操作,实际需求不是硬删除只是更新一个删除状态;保存对象操作之前需要做相应的数据校验和数据格式的转换等等,自动转换成REST服务,是否支持自定义功能?

分页+排序查询(这个与以往的习惯有点不同)

http://localhost:8080/user?sort=id,desc&size=2

sort desc 这类关键字是否可以自定义?因为运维方面会对这些关键字做防SQL注入(waf)

  1. {

  2.  "_embedded": {

  3.    "users": [

  4.      {

  5.        "userName": "Yezhwi4",

  6.        "password": "123",

  7.        "phone": "12345678901",

  8.        "locked": 0,

  9.        "_links": {

  10.          "self": {

  11.            "href": "http://localhost:8080/user/17"

  12.          },

  13.          "user": {

  14.            "href": "http://localhost:8080/user/17"

  15.          }

  16.        }

  17.      },

  18.      {

  19.        "userName": "Yezhwi5",

  20.        "password": "123",

  21.        "phone": "12345678901",

  22.        "locked": 0,

  23.        "_links": {

  24.          "self": {

  25.            "href": "http://localhost:8080/user/16"

  26.          },

  27.          "user": {

  28.            "href": "http://localhost:8080/user/16"

  29.          }

  30.        }

  31.      }

  32.    ]

  33.  },

  34.  "_links": {

  35.    "first": {

  36.      "href": "http://localhost:8080/user?page=0&size=2&sort=id,desc"

  37.    },

  38.    "self": {

  39.      "href": "http://localhost:8080/user"

  40.    },

  41.    "next": {

  42.      "href": "http://localhost:8080/user?page=1&size=2&sort=id,desc"

  43.    },

  44.    "last": {

  45.      "href": "http://localhost:8080/user?page=5&size=2&sort=id,desc"

  46.    },

  47.    "profile": {

  48.      "href": "http://localhost:8080/profile/user"

  49.    }

  50.  },

  51.  "page": {

  52.    "size": 2,

  53.    "totalElements": 11,

  54.    "totalPages": 6,

  55.    "number": 0

  56.  }

  57. }

自定义查询方法

根据给定的字段查找相应表中的数据对象。比如在上一篇中定义的User实体,需要一个按照userName(假如数据库中唯一)值查到与之对应的数据对象返回,只需要在UserRopository中定义如下代码:

  1. import com.gemantic.model.User;

  2. import com.google.common.base.Optional;

  3. import org.springframework.data.jpa.repository.JpaRepository;

  4. import org.springframework.data.repository.query.Param;

  5. import org.springframework.data.rest.core.annotation.RepositoryRestResource;

  6. /**

  7. * @author Yezhiwei

  8. * @date 17/12/16

  9. */

  10. @RepositoryRestResource(path = "user")

  11. public interface UserRepository extends JpaRepository<User, Long> {

  12.    Optional<User> findByUserName(@Param("userName") String userName);

  13. }

所有的查询方法,默认转成search路径下,如: http://localhost:8080/user/search/findByUserName?userName=Yezhiwei

上图中自动转成的URL是按方法名,若要更改该查询方法所暴露的URL,在方法上使用 @RestResource注释

  1. @RestResource(path = "name", rel = "name")

  2. Optional<User> findByUserName(@Param("userName") String userName);

输入 http://localhost:8080/user/search/ 查看user下的所有查询方法有哪些:

查看资源user下所有查询方法 /user/search

path = "name" 将路径参数findByUserName转为name /user/search/name

rel = "name" 更改参数findByUserName转为name

多条件查询

如果匹配多个条件查询,则用And和Or连接,比如:

  1. import com.gemantic.model.User;

  2. import com.google.common.base.Optional;

  3. import org.springframework.data.jpa.repository.JpaRepository;

  4. import org.springframework.data.repository.query.Param;

  5. import org.springframework.data.rest.core.annotation.RepositoryRestResource;

  6. import org.springframework.data.rest.core.annotation.RestResource;

  7. import java.util.List;

  8. /**

  9. * @author Yezhiwei

  10. * @date 17/12/16

  11. */

  12. @RepositoryRestResource(path = "user")

  13. public interface UserRepository extends JpaRepository<User, Long> {

  14.    ...

  15.    @RestResource(path = "nameAndPhone", rel = "nameAndPhone")

  16.    List<User> findByUserNameAndPhone(@Param("userName") String userName, @Param("phone") String phone);

  17. }

排序

可以在方法名称的结尾处添加OrderBy,实现结果集排序。比如可以按照User的userName降序排列

  1. import com.gemantic.model.User;

  2. import com.google.common.base.Optional;

  3. import org.springframework.data.jpa.repository.JpaRepository;

  4. import org.springframework.data.repository.query.Param;

  5. import org.springframework.data.rest.core.annotation.RepositoryRestResource;

  6. import org.springframework.data.rest.core.annotation.RestResource;

  7. import java.util.List;

  8. /**

  9. * @author Yezhiwei

  10. * @date 17/12/16

  11. */

  12. @RepositoryRestResource(path = "user")

  13. public interface UserRepository extends JpaRepository<User, Long> {

  14.    ...

  15.    @RestResource(path = "nameStartsWith", rel = "nameStartsWith")

  16.    List<User> findByUserNameStartsWithOrderByUserNameDesc(@Param("userName") String userName);

  17. }

隐藏某个字段

比如在实体对象User中,不希望password序列化为JSON,Spring Data REST默认使用的是JackSon,则我们就可以在需要隐藏的字段添加@JsonIgnore即可

  1. @Data

  2. @Entity

  3. public class User {

  4.    @Id

  5.    @GeneratedValue(strategy= GenerationType.AUTO)

  6.    private Long id;

  7.    private String userName;

  8.    @JsonIgnore

  9.    private String password;

  10.    private String phone;

  11.    private Integer locked;

  12. }

隐藏自定义的查询方法

只需要在方法上添加 @RestResource(exported=false) 即可,如:

  1. /**

  2. * @author Yezhiwei

  3. * @date 17/12/16

  4. */

  5. @RepositoryRestResource(path = "user")

  6. public interface UserRepository extends JpaRepository<User, Long> {

  7. //    @RestResource(path = "name", rel = "name")

  8.    @RestResource(exported = false)

  9.    Optional<User> findByUserName(@Param("userName") String userName);

  10.    @RestResource(path = "nameAndPhone", rel = "nameAndPhone")

  11.    List<User> findByUserNameAndPhone(@Param("userName") String userName, @Param("phone") String phone);

  12.    @RestResource(path = "nameStartsWith", rel = "nameStartsWith")

  13.    List<User> findByUserNameStartsWithOrderByUserNameDesc(@Param("userName") String userName);

  14. }

屏蔽自动化方法(repository CRUD) extendsCrudRepository

在实际生产环境中,不会真正删除用户数据,此时不希望DELETE的提交方式生效,可以添加@RestResource注解,并设置exported=false,即可屏蔽Spring Data REST的自动化方法 ,只需要写如下代码:

  1. /**

  2. * @author Yezhiwei

  3. * @date 17/12/16

  4. */

  5. @RepositoryRestResource(path = "user")

  6. public interface UserRepository extends CrudRepository<User, Long> {

  7.    ...

  8.    @RestResource(path = "nameStartsWith", rel = "nameStartsWith")

  9.    List<User> findByUserNameStartsWithOrderByUserNameDesc(@Param("userName") String userName);

  10.    @Override

  11.    @RestResource(exported = false)

  12.    void delete(Long id);

  13. }

修改对象返回值json数据中的key

默认是User对象的属性,在一些特殊情况下,需要修改json返回值中的key,需要定义如下代码:

  1. import org.springframework.beans.factory.annotation.Value;

  2. import org.springframework.data.rest.core.config.Projection;

  3. /**

  4. *

  5. */

  6. @Projection(name = "vu",types = User.class)

  7. public interface VirtualUser {

  8.    @Value("#{target.userName}-#{target.phone}")

  9.    String getFullInfo();

  10.    @Value("#{target.locked}")

  11.    Integer getStatus();

  12. }

这里把User中的userName和phone合并成一列,locked重新命名为stauts,这里需要注意方法名前面一定要加get,不然无法序列化为JSON数据。启动服务,试一试

http://localhost:8080/user/1

http://localhost:8080/user/1?projection=vu

参考 Customizing Spring Data REST


原文作者:HelloTech技术派;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-12-05

  • 博文量
    181
  • 访问量
    73730