使用SpringMVC实现RESTFul接口

来源:互联网 发布:软件开发的几个阶段 编辑:程序博客网 时间:2024/05/19 14:17

如果我们要给其它系统提供API接口,那么我们写的方法要返回ResponseEntity<XXX>,其它系统用httpclient获取的ResponseEntity的getBody就是XXX对象的字符串形式。

如果我们给自己系统的前台提供资源,返回用@ResponseBody,返回用XXX即可。

当我们要返回状态码时, @ResponseBody下的方法返回类型要使用ResponseEntity,如ResponseEntity<User>,ResponseEntity<Void>等,这样状态码会被写到响应头中,而不是响应体中

查询:返回ResponseEntity<User>

    @RequestMapping(value = "{id}", method = RequestMethod.GET)
    @ResponseBody //有ResponseEntity,其实不用 @ResponseBody也能返回json的
    public ResponseEntity<User> queryUserById(@PathVariable("id") Long id) {
        try {
            User user = userService.getUserById(id);
            if (null == user) {
                // 资源不存在,响应404
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
            }
            // 资源存在,响应200
            // return ResponseEntity.status(HttpStatus.OK).body(user);
            return ResponseEntity.ok(user);
        } catch (Exception e) {
            e.printStackTrace();
        }

//若发生异常,就500错误
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
    }

新增:返回ResponseEntity<Void>

这里要注意,你的请求,请求头content-type:application/json是必须写的(编码类型)

请求体中写json字符串,比如{"key":"value"},这要配合方法中的@RequestBody 

请求头中要与请求体一致

区别于表单提交,如果没有@RequestBody ,那么请求头中可以不用content-type:application/json,当传入age=20&password=123这样的参数能请求成功。

如果代码中没有@RequestBody ,但我们传入了{"key":"value"}这种格式的,那么值都为空。

一般都会有@RequestBody

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<Void> saveUser(@RequestBody User user) {
        try {
            Boolean bool = userService.saveUser(user);
            if (bool) {
                // 新增成功,响应201
                return ResponseEntity.status(HttpStatus.CREATED).build();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 新增失败,响应500
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }

更新:返回ResponseEntity<Void>

    @RequestMapping(method = RequestMethod.PUT)
    public ResponseEntity<Void> updateUser(@RequestBody User user) {
        try {
            Boolean bool = userService.updateUser(user);
            if (bool) {
                // 更新成功,响应204
                return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 新增失败,响应500
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }

这里要注意,更新时如果使用了@RequestBody,那么用PUT请求时,不用担心PUT请求无法提交表单数据的问题的问题,因为传的参数不是表单型的(age=20&password=123),而是JSON型的({"key":"value"})。

那么如果方法中没有使用@RequestBody,那么要用表单提交时,要在web.xml中添加

<!-- 解决PUT请求无法提交表单数据的问题 -->

<filter>
<filter-name>HttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

过滤器


删除:返回ResponseEntity<Void>

        @RequestMapping(value = "{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteUser(@PathVariable(value = "id") Long id) {
        try {
User user = userService.queryUserById(id);
if (null == user) {
// 资源不存在,响应404
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
            Boolean bool = this.userService.deleteUser(id);
            if (bool) {
                // 删除成功,响应204
                return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 删除失败,响应500
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }

前面方法要求我们使用httpclient时使用delete,否则报错。

如果仅仅是我们自己的前台系统调用ajax请求去删除资源,我们就不需要使用restful风格。我们使用普通的GET请求就可以了。

注意,如果想使用表单形式的删除,那么不要使用@PathVariable,用@RequestParam即可,另外,还要在web.xml中配置

<!-- 
将POST请求转化为DELETE或者是PUT要用_method指定真正的请求方法,可以使DELETE或PUT
-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

在请求中还要添加_method=DELETE(通过ajax请求时,type就是POST),最终的url就是/rest/...?id=xxx&_method=DELETE。后台不用去判断_method参数,只需要method = RequestMethod.DELETE 就可以进去了。

总结:使用@RequestBody XXX xxx做请求体中的值和XXX xxx做参数是有本质区别的,后者是请求参数,类似于?xxx=xxx&xxx2=xxx2,后者不是真正的REST风格,@RequestParam也不是真正的REST风格。

当有这两个过滤器时,不影响我们使用restTemplate。

200查询成功,201创建成功,204修改成功、删除成功,404资源未找到、400参数有误、500系统内部错误

原创粉丝点击