Rest 实践
结合之前所学的内容,这篇教程将基于 SpringMVC 构建一个真正的 Rest 服务。
首先构建 Service 层,即逻辑层,创建接口 PersonService:
public interface PersonService {
List<Person> get();
Person get(int id);
void add(int id, String name);
void delete(int id);
}
同时创建对应的 PersonServiceImpl 层,对应的实现可以留空。
然后在前面的 PersonController 基础上,加入更多的 API 支持:
@ResponseStatus(value = HttpStatus.NOT_FOUND)
class ResourceNotFoundException extends RuntimeException {
}
@RestController
@RequestMapping("/person")
public class PersonController {
@Autowired
private PersonService personService;
@RequestMapping(method = RequestMethod.GET)
public List<Person> getAllPerson() {
return personService.get();
}
@RequestMapping(value = "/{id:[\\d]+}", method = RequestMethod.GET)
public Person getPerson(
@PathVariable(value = "id") int id
)
{
Person result = personService.get(id);
if (result == null)
{
throw new ResourceNotFoundException();
}
return result;
}
@RequestMapping(value = "", method = RequestMethod.POST)
public void addPerson(@RequestParam int id, @RequestParam String name)
{
personService.add(id, name);
}
@RequestMapping(value = "/{id:[\\d]+}", method = RequestMethod.DELETE)
public void deletePerson(
@PathVariable(value = "id") int id
)
{
personService.delete(id);
}
}
这样一个简单的 Rest 框架就搭建好了。
对于 PersonService 的实现部分,我们再抽取一个新的 PersonDao 接口:
public interface PersonDao {
List<Person> get();
Person get(int id);
void add(int id, String name);
void delete(int id);
}
PersonService 的实现可以面向 PersonDao 编程:
@Service
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonDao personDao;
@Override
public List<Person> get() {
return personDao.get();
}
@Override
public Person get(int id) {
return personDao.get(id);
}
@Override
public void add(int id, String name) {
personDao.add(id, name);
}
@Override
public void delete(int id) {
personDao.delete(id);
}
}
这样的做的好处是,把 Service 层和 Dao 层做到了权责分离,Service 层可以引入更多的业务逻辑,而 Dao 层则只关心数据的存取。同时由于是面向接口编程,Dao 层的具体实现也可以很灵活。
下面我们基于 SQLite 和 Spring 本身的 Dao 支持实现一个简单的 Dao 层。
首先在 pom.xml 中加入有关依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.8.11.2</version>
</dependency>
然后实现我们的 Dao 层:
@Repository
public class PersonDaoImpl implements PersonDao {
private JdbcTemplate jdbcTemplate;
@Autowired
public PersonDaoImpl(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public List<Person> get() {
String sql = "select * from person";
return this.jdbcTemplate.query(sql, ROW_MAPPER);
}
@Override
public Person get(int id) {
String sql = "select * from person where id = ?";
try {
return this.jdbcTemplate.queryForObject(sql, new Object[]{id}, ROW_MAPPER);
}
catch (EmptyResultDataAccessException e)
{
return null;
}
}
@Override
public void add(int id, String name) {
String sql = "insert into person values (?, ?)";
this.jdbcTemplate.update(sql, id, name);
}
@Override
public void delete(int id) {
String sql = "delete from person where id = ?";
this.jdbcTemplate.update(sql, id);
}
private static final RowMapper<Person> ROW_MAPPER = (rs, rowNum) -> new Person(
rs.getInt("id"),
rs.getString("name"));
}
在 AppConfig 中加入数据库的配置:
@Configuration
@EnableWebMvc
@ComponentScan("com.skyline")
public class AppConfig {
@Bean
DataSource getDataSource()
{
SQLiteDataSource dataSource = new SQLiteDataSource();
dataSource.setUrl("jdbc:sqlite:D:/mydata.db");
return dataSource;
}
}
当然这里要求数据库是提前建好的,使用了下面的 schema:
CREATE TABLE person(id INTEGER, name VARCHAR);
将编译生成的 class 文件和依赖 jar 包(spring-jdbc,spring-tx,sqlite-jdbc)拷贝到 Tomcat 目录下,运行 Tomcat。使用 Curl 或者浏览器就可以测试我们的 Rest 服务了。