Spring Data Rest!五分钟帮我们实现Rest服务

Spring Data Rest!几分钟帮我们实现Rest服务

一、概述

一直认为,Spring Data是与第三方组件进行数据交换的全家桶的整合,比如Spring Data Jpa是数据库使用,Spring Data LDAP是LDAP的使用,Spring Data Redis是Redis的使用,Spring Data Elasticsearch是Elasticsearch的使用。

然而,不起眼的地方有一个Spring Data Rest,按照常规定义,它是与Rest组件的数据交互?

非也,Spring Data Rest只是一种快速提供rest服务的方式,通过与Spring Data xxx整合,快速实现CRUD,自动将repository 自动输出为REST资源,目前支持Spring Data JPA、Spring Data MongoDB、Spring Data Neo4j、Spring Data GemFire、Spring Data Cassandra的 repository 自动转换成REST服务。

Spring Data REST把我们需要编写的大量REST模版接口做了自动化实现。

所以,五分钟实现rest服务不是梦,比我写文章都快!

首发地址:
品茗IT-同步发布

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

二、配置

本文以Spring Data JPA结合Spring Data Rest为例,描述如何使用Spring Data Rest。

2.1 依赖

引入spring-boot-starter-data-rest和spring-boot-starter-data-jpa,使用Spring Data JPA,就必须引入mysql-connector-java和数据源。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

2.2 配置文件

配置文件中只需要配置数据源和jpa相关信息即可,如:

server.port=8040

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/boot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=cff
spring.datasource.password=123456

spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
spring.datasource.dbcp2.max-wait-millis=60000
spring.datasource.dbcp2.min-idle=20
spring.datasource.dbcp2.initial-size=2
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
spring.datasource.dbcp2.validation-query=SELECT 1
spring.datasource.dbcp2.test-while-idle=true
spring.datasource.dbcp2.test-on-borrow=true
spring.datasource.dbcp2.test-on-return=false

spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

三、配置Rest访问

需要在实体上加上Spring data jpa 需要的注解:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name = "user_info")
public class UserInfo {
    @Id
    @Column(name = "user_name")
    private String userName;
    @JsonIgnore
    private String passwd;
    private String name;
    private String mobile;
    private String valid;
    @Column(name = "user_type")
    private String userType;

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserName() {
        return userName;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    public String getPasswd() {
        return passwd;
    }

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

    public String getName() {
        return name;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getMobile() {
        return mobile;
    }

    public void setValid(String valid) {
        this.valid = valid;
    }

    public String getValid() {
        return valid;
    }

    public void setUserType(String userType) {
        this.userType = userType;
    }

    public String getUserType() {
        return userType;
    }

}

对于不想暴漏的字段,使用@JsonIgnore即可。

同时,在自定义的Repository中加入@RepositoryRestResource注解:

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;

import com.cff.springbootwork.domain.UserInfo;

/**
 * collectionResourceRel是json的最外层显示名称,path是访问路径
 * 
 * @author fufei
 *
 */
@RepositoryRestResource(collectionResourceRel = "user", path = "user")
public interface UserInfoDao extends JpaRepository<UserInfo, String> {
    List<UserInfo> findByName(@Param("name") String name);

    /**
     * 不暴漏删除接口
     */
    @Override
    @RestResource(exported = false)
    void deleteById(String id);

    @Override
    @RestResource(exported = false)
    void delete(UserInfo entity);
}

对于不需要暴漏的接口,可以使用@RestResource(exported = false)隐藏该接口。

Spring Data Rest并不妨碍你传统的写法,你仍可以定义自己的controller、service和dao等!

四、使用方法

Springboot启动项目以后,我们就可以直接使用rest服务了。

4.1 查询

查询所有用户,使用get请求发送http://127.0.0.1:8040/user

{
  "_embedded" : {
    "user" : [ {
      "name" : null,
      "mobile" : "4444",
      "valid" : "0",
      "userType" : "1",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8040/user/15607110725"
        },
        "userInfo" : {
          "href" : "http://127.0.0.1:8040/user/15607110725"
        }
      }
    }, {
      "name" : null,
      "mobile" : "3242",
      "valid" : null,
      "userType" : "2",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8040/user/3453sdf"
        },
        "userInfo" : {
          "href" : "http://127.0.0.1:8040/user/3453sdf"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8040/user{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://127.0.0.1:8040/profile/user"
    },
    "search" : {
      "href" : "http://127.0.0.1:8040/user/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}

上面 _links 节点下的内容提示我们

  • 可以使用http://127.0.0.1:8040/user{?page,size,sort}进行分页查询。
  • 使用http://127.0.0.1:8040/profile/user查看user实体相关。
  • 使用http://127.0.0.1:8040/user/search进行search查询(自定义的查询接口);
  • 每条记录都有提示如何根据主键进行查询的方法。

输入http://127.0.0.1:8040/user/15607110725,就能查出15607110725这条记录:

{
  "name" : "cff",
  "mobile" : "4444",
  "valid" : "0",
  "userType" : "1",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8040/user/15607110725"
    },
    "userInfo" : {
      "href" : "http://127.0.0.1:8040/user/15607110725"
    }
  }
}

输入http://127.0.0.1:8040/user?page=0&size=10&sort=mobile,desc,可以进行分页排序查询,这里的排序字段sort是根据mobile字段desc排序的:

{
  "_embedded" : {
    "user" : [ {
      "name" : "cff",
      "mobile" : "4444",
      "valid" : "0",
      "userType" : "1",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8040/user/15607110725"
        },
        "userInfo" : {
          "href" : "http://127.0.0.1:8040/user/15607110725"
        }
      }
    }, {
      "name" : null,
      "mobile" : "3242",
      "valid" : "0",
      "userType" : "1",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8040/user/3453sdf"
        },
        "userInfo" : {
          "href" : "http://127.0.0.1:8040/user/3453sdf"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8040/user"
    },
    "profile" : {
      "href" : "http://127.0.0.1:8040/profile/user"
    },
    "search" : {
      "href" : "http://127.0.0.1:8040/user/search"
    }
  },
  "page" : {
    "size" : 10,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}

输入http://127.0.0.1:8040/user/search,可以显示当前可以用来search的接口列表:

{
  "_links" : {
    "findByName" : {
      "href" : "http://127.0.0.1:8040/user/search/findByName{?name}",
      "templated" : true
    },
    "self" : {
      "href" : "http://127.0.0.1:8040/user/search"
    }
  }
}

表示,可以用http://127.0.0.1:8040/user/search/findByName{?name}来进行search操作。

输入http://127.0.0.1:8040/user/search/findByName?name=cff

{
  "_embedded" : {
    "user" : [ {
      "name" : "cff",
      "mobile" : "4444",
      "valid" : "0",
      "userType" : "1",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8040/user/15607110725"
        },
        "userInfo" : {
          "href" : "http://127.0.0.1:8040/user/15607110725"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8040/user/search/findByName?name=cff"
    }
  }
}

4.2 保存

使用POST方式访问 http://localhost:8040/user并提交如下的JSON 数据:

{
    "userName":"test",
    "passwd":"123123",
    "mobile":"21312312",
    "name":"heihei"
}

这里,因为上面实体userInfo的passwd字段加了@JsonIgnore注解,提交的json中,passwd是无效的。

官方文档中说可以把@RestResource(exported = false)加到字段上,经试验无效,所以遇到这种情况还是手写controller吧。

4.3 更新

跟保存方式一样,已经存在的字段,如果这次不填,就被更新为null了。

4.4 删除

使用DELETE方式请求 http://localhost:8040/user/test

会提示405 Method Not Allowed,这是因为我们在delete方法上加了@RestResource(exported = false)注解,去掉该注解即可,注意是delete方法,deleteById方法加不加都无所谓。

重新请求,成功删除。

五、总结

Spring Data Rest 官网 很详细的说明了如何使用Spring Data Rest,尽管Spring Data Rest有很大的局限性,但5分钟搞定一个Rest服务真的很赞,而且不影响传统写法,很适合快速开发。

快速构建项目

Spring项目快速开发工具:

一键快速构建Spring项目工具

一键快速构建SpringBoot项目工具

一键快速构建SpringCloud项目工具

一站式Springboot项目生成

Mysql一键生成Mybatis注解Mapper

Spring组件化构建

SpringBoot组件化构建

SpringCloud服务化构建

喜欢这篇文章么,喜欢就加入我们一起讨论SpringBoot使用吧!


品茗IT交流群
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容