基于MVCRESTful格调的实现

1.RESTful格调论述

REST服务是一种ROA(Resource-Oriented Architecture,面向资源的架构)利用。次要特点是办法信息存在于HTTP协定的办法中(GET,POST,PUT,DELETE),作用域存在于URL中。例如,在一个获取设施资源列表的GET申请中,办法信息是GET,作用域信息是URI种蕴含的对设施资源的过滤、分页和排序等条件

==良好的REST API不须要任何文档==

1.1REST格调资源门路

REST格调的资源门路设计是面向资源的,==资源的名称==应该是精确形容该资源的==名词==。

资源门路概览:sheme://host:port/path?queryString

例:http://localhost:8080/bywlstudio/users/user?username=xiuer

1.2HTTP办法
GET用于==读取==、==检索==、==查问==、==过滤==资源

PSOT用于==创立==一个资源

PUT用于==批改==、==更新==资源、==创立客户端保护主键信息的资源==

DELETE用于==删除==资源

资源地址和HTTP办法联合在一起就能够实现对资源的残缺定位

1.3RESTful格调API设计

上文讲述了通过HTTP办法和资源门路对服务器的一个资源进行定位的过程

接下来看一个REST格调API的设计

性能形容
增加/创立POST/users
PUT/users{id}1
删除DELETE/users/{id}
批改/更新PUT/users/{id}
查问全副GET/users
主键查问GET/users/{id}
GET/users?id=26
分页作用域查问GET/users?start=0&size=10
GET/users?07,2019-07,2020

能够看到通过这个RESTAPI都是通过对==同一个资源==的操作,所不同的就是通过不同的==HTTP办法==来实现对资源不同的解决。

2.MVCREST的反对

1.1次要通过注解来实现
  • @Controller声名一个解决申请的控制器
  • @RequestMapping申请映射地址,它存在几个子注解对于实现REST格调来说更加具备==语义性==

    • @GETMapping ==GET申请==
    • @PUTMapping ==PUT申请==
    • @POSTMapping ==POST申请==
    • @DELETEMapping ==DELETE申请==
  • @ResponseBody 将响应内容转换为JSON格局
  • @RequestBody 申请内容转换为JSON格局
  • @PathVariable("id")用于绑定一个参数
  • @RESTController 等同于@Controller+@ResponseBody在类上写了这个注解,标识这个类的所有办法只==返回数据==,而不进行==视图跳转==
1.2返回HTTP状态码

REST格调API一个最显明的特点通过返回对应的HTTPStatus来判断客户端的操作是否实现

==上面是spring中对于Http状态码形容的枚举类,本文列举了常见的状态码==(读者若对此感兴趣能够查看HttpStatus源码)

public enum HttpStatus{    OK(200, "OK"),//用于服务器有实体响应    CREATED(201, "Created"),//创立了新实体,响应该实体    NO_CONTENT(204, "No Content"),//服务器失常响应,但无实体响应    BAD_REQUEST(400, "Bad Request"),//客户端申请语法错误    NOT_FOUND(404, "Not Found"),//指标资源不存在    INTERNAL_SERVER_ERROR(500, "Internal Server Error"),//服务器外部谬误    NOT_IMPLEMENTED(501, "Not Implemented"),//服务器不反对以后申请}

Spring返回状态码是通过@ResponseStatus注解或者ResponseEntity<?>类实现的。

==@ResponseStatus形式==

@GetMapping(path = "/user/{id}" , produces = "application/json;charset=utf-8")@ResponseStatus(HttpStatus.OK)public User findUserById(@PathVariable("id")Integer id){    User user = userService.findUserById(id);    return user ;}

==ResponseEntity<?>==形式

@GetMapping(produces = "application/json;charset=utf-8")public ResponseEntity<List<User>> findAll(){    List<User> users = userService.findAll();    return new ResponseEntity<List<User>>(users , HttpStatus.OK);}
1.3因为MVC默认不反对PUTDELETE办法,所以须要手动开启

tomcat服务器的web.xml文件中开启一下配置

<servlet>        <servlet-name>default</servlet-name>        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>        <init-param>            <param-name>debug</param-name>            <param-value>0</param-value>        </init-param>        <init-param>            <param-name>listings</param-name>            <param-value>false</param-value>        </init-param>        <init-param>        <param-name>readonly</param-name>        <param-value>true</param-value><!--开启这个-->        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>

在我的项目的web.xml中配置

<filter>    <filter-name>HiddenHttpMethodFilter</filter-name>    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  </filter>  <filter-mapping>    <filter-name>HiddenHttpMethodFilter</filter-name>    <servlet-name>dispathcherServlet</servlet-name>  </filter-mapping>

3.MVC实现REST代码实现

3.1实例环境
  • JDK1.8
  • maven3.60
  • tomcat9
3.2API设计
URIDescriptionResponseHTTPStatus
==GET==/users获取全副用户JSON200
==GET==/users/{id}获取指定主键的用户JSON200
==PUT==/users/{id}批改指定的主键的用户信息JSON200/201
==POST==/users减少一个用户JSON201
==DELETE==/users/{id}删除一个用户void204
3.3管制层代码
@RestController@RequestMapping("/users")public class UserControler {    @Autowired    private IUserService userService ;    //REST格调实现办法    /**     * 查问所有     * @return     */    @GetMapping(produces = "application/json;charset=utf-8")    public ResponseEntity<List<User>> findAll(){        List<User> users = userService.findAll();        return new ResponseEntity<List<User>>(users , HttpStatus.OK);    }    /**、     * 依据ID查问     * @param id     * @return     */    @GetMapping(path = "/{id}" , produces = "application/json;charset=utf-8")    @ResponseStatus(HttpStatus.OK)    public User findUserById(@PathVariable("id")Integer id){        User user = userService.findUserById(id);        return user ;    }    /**     * 减少一个用户     * 返回该用户     */    @PostMapping(produces = "application/json;charset=utf-8")    @ResponseStatus(HttpStatus.CREATED)    public User addUser(@RequestBody User user){        User newUser = userService.addUser(user);        return newUser ;    }    /**     * 更新     * @param user     */    @PutMapping(path = "/{id}" ,produces = "application/json;charset=utf-8")    public ResponseEntity<User> updateUser(@PathVariable("id") Integer id , @RequestBody User user){        user.setUid(id);        //资源是否批改        boolean flag = userService.updateUser(user);        User deUser = userService.findUserById(id);        if(flag)            return new ResponseEntity<User>(deUser,HttpStatus.CREATED);        return new ResponseEntity<User>(deUser,HttpStatus.OK);    }    @DeleteMapping(path = "/{id}"  , produces = "application/json;charset=utf-8")    @ResponseStatus(HttpStatus.NO_CONTENT)    public void delUser(@PathVariable("id") Integer id){        User user = userService.findUserById(id);        userService.delUser(id);    }}

更多原创文章和Java学习材料@公众号MakerStack


  1. 创立客户端保护主键信息的资源 ↩