题记:前段时间经理让写个关于新闻的后台,要求用到Restful风格,且前后端分离。
这里面有三个方面的问题需要记录一下:Restful、跨域、图片或文件的上传。
今天先记录下关于Restful。
关于RESTFul,之前是在淘淘商城中了解的。一直是学习,没有真正用到项目中,现在终于派上了用场。关于RESTful的知识也是部分摘抄于淘淘商城笔记,具体如下:
1.什么是RESTful
在了解RESTful之前先来了解一下,REST
1.1什么是REST
rest不就是放松一下的意思嘛,哈哈,的确用它可以让你放松一下。
- REST是web服务的一种架构风格(1.3)
- 使用http、uri等广泛流行的标准和协议
- 轻量级、跨平台、跨语言的架构设计
- 是一种设计风格,不是一种标准也不是一种软件,而是一种思想
1.2什么是RESTful
- RESTful对应的中文是REST式的
- RESTful web service是一种常见的REST的应用,遵守了REST风格的web服务
- REST式的web服务式一种ROA(面向资源的架构)
1.3REST架构的风格(原则)
- 网络上的所有事物都可被抽象为资源(Resource)
- 每个资源都有一个唯一的资源标识符(Resource Identifier)
- 同一资源具有多种表现形式(xml、json等)
- 对资源的各种状态不会改变资源标识符
- 所有的操作都是无状态的(Stateless)
- 符合REST原则的架构方式就可以称为RESTful
无状态的解释:无状态性使得客户端与服务器不必保存对方的详细信息,服务器只需处理当前Request,而不必了解Request的历史,从而可以释放资源,让服务器充分利用Pool技术来提高稳定性和性能。
1.4RESTful风格的特色
最大的特色就是使用URI来标识资源
URI:http://example.com/users/
URL:http://example.com/users/{user}{one for each user}
从上面可以看出:uri可以指向多个,而url只能指向一个。
具体情况原始接口与RESTful写法的对比:
原始接口写法:
Http://127.0.0.1/user/query/1 -- GET请求,查询用户数据
Http://127.0.0.1/user/save -- POST 新增用户数据
Http://127.0.0.1/user/update -- POST 更新数据
Http://127.0.0.1/user/delete/id --POST/GET 删除数据
RESTful的写法:针对原始接口的写法,RESTful创造者提出:你明知道是get请求,那就是一个查询的请求没有必要写个query;明知道是post请求,那就是新增数据也没有必要写个save,造成数据冗余。便改为如下方式:
Http://127.0.0.1/user/{id} -- GET请求,查询用户数据
Http://127.0.0.1/user/ -- POST 新增用户数据
Http://127.0.0.1/user/ -- PUT更新数据
Http://127.0.0.1/user/{id}--DELETE删除数据
2.REST接口的定义
3.响应设计
- Content body仅仅用了传输数据
- 数据要做到拿来就用原则,不需要“拆箱”的过程
- 用了描述数据或者请求的元数据放Header中,例如X-Result-Fields
/**
* 查询用户
* @param id
* @return
*/
@RequestMapping(value="{id}", method=RequestMethod.GET)
public ResponseEntity<User> queryUser(@PathVariable("id")Integer id){
try {
User user = this.userService.getUserById(id);
if (null==user) {
// 资源不存在响应404
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
// 资源存在,响应200
return ResponseEntity.ok(user);
} catch (Exception e) {
e.printStackTrace();
}
// 出错响应500
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
测试:(测试工具的安装与使用)
/**
* 新增用户
* @param user
* @return
*/
@RequestMapping(method=RequestMethod.POST)
public ResponseEntity<Void> saveUser(User user){
try {
int count = this.userService.saveUser(user);
if(count!=0){
return ResponseEntity.status(HttpStatus.CREATED).build();
}
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
/**
* 更新用户
* @param user
* @return
*/
@RequestMapping(method=RequestMethod.PUT)
public ResponseEntity<Void> updateUser(User user){
try {
int count = this.userService.updateUser(user);
if(count==0){
//说明更新的资源不存在
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where id = null' at line 3
### The error may involve com.test.dao.UserMapper.updateByPrimaryKeySelective-Inline
### The error occurred while setting parameters
### SQL: update user where id = ?
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where id = null' at line 3
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where id = null' at line 3
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
/**
* 删除用户
* @param id
* @return
*/
@RequestMapping(value="{id}",method=RequestMethod.DELETE)
public ResponseEntity<Void> deleteUser(@PathVariable("id") Integer id){
try {
int count= this.userService.deleteUser(id);
if(count==0){
// 删除的资源不存在
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
测试:
package com.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.pojo.User;
import com.test.service.UserService;
@Controller
@RequestMapping("/user")
public class RestUserController {
@Autowired
private UserService userService;
/**
* 查询用户
* @param id
* @return
*/
@RequestMapping(value="{id}", method=RequestMethod.GET)
public ResponseEntity<User> queryUser(@PathVariable("id")Integer id){
try {
User user = this.userService.getUserById(id);
if (null==user) {
// 资源不存在响应404
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
// 资源存在,响应200
return ResponseEntity.ok(user);
} catch (Exception e) {
e.printStackTrace();
}
// 出错响应500
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
/**
* 新增用户
* @param user
* @return
*/
@RequestMapping(method=RequestMethod.POST)
public ResponseEntity<Void> saveUser(User user){
try {
int count = this.userService.saveUser(user);
if(count!=0){
return ResponseEntity.status(HttpStatus.CREATED).build();
}
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
/**
* 更新用户
* @param user
* @return
*/
@RequestMapping(method=RequestMethod.PUT)
public ResponseEntity<Void> updateUser(User user){
try {
int count = this.userService.updateUser(user);
if(count==0){
//说明更新的资源不存在
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
/**
* 删除用户
* @param id
* @return
*/
@RequestMapping(value="{id}",method=RequestMethod.DELETE)
public ResponseEntity<Void> deleteUser(@PathVariable("id") Integer id){
try {
int count= this.userService.deleteUser(id);
if(count==0){
// 删除的资源不存在
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
package com.test.service;
import com.test.pojo.User;
public interface UserService {
public User getUserById(int id);
public int saveUser(User user);
public int updateUser(User user);
public int deleteUser(int id);
}
package com.test.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.test.dao.UserMapper;
import com.test.pojo.User;
import com.test.service.UserService;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
public User getUserById(int id) {
return this.userMapper.selectByPrimaryKey(id);
}
public int saveUser(User user) {
int count = this.userMapper.insertSelective(user);
return count;
}
public int updateUser(User user) {
int count=this.userMapper.updateByPrimaryKeySelective(user);
return count;
}
public int deleteUser(int id) {
int count = this.userMapper.deleteByPrimaryKey(id);
return count;
}
}