使用SpringMVC实现RESTFul接口

xiaoxiao2021-02-28  105

如果我们要给其它系统提供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系统内部错误

转载请注明原文地址: https://www.6miu.com/read-28625.html

最新回复(0)