Spring 初探(十)(Spring RESTful web 应用)
来源:互联网 发布:windows update是什么 编辑:程序博客网 时间:2024/05/24 05:34
Spring RESTful web的一个简单应用场景如 在网络应用中对数据库对象进行
有关增删改查的工作 如对于关注的对象的存取及删除都是可以进行的。
下面的部分使用了Spring 初探(九)的示例代码 搭建Spring RESTful web 的简单示例应用
先对一些基本概念进行
简要介绍。
HTTP具有如下方法来操作数据交互:
GET 不在request中设定body而返回body
DELETE remove URI做指定的资源
PUT update URI所指定的资源 使用需要发送GET所得到的类似结果
POST add or append URI所指定的资源 也可能被类似PUT的方法对待
简要介绍。
HTTP具有如下方法来操作数据交互:
GET 不在request中设定body而返回body
DELETE remove URI做指定的资源
PUT update URI所指定的资源 使用需要发送GET所得到的类似结果
POST add or append URI所指定的资源 也可能被类似PUT的方法对待
下面来看一个示例部分代码:
Ex:
Ex:
package bookmarks;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import org.springframework.http.ResponseEntity;import org.springframework.web.servlet.support.ServletUriComponentsBuilder;import java.net.URI;import java.util.Collection;/** * Created by ehang on 2016/12/31. */@RestController@RequestMapping("/{userId}/bookmarks")class BookmarkRestController { private final BookmarkRepository bookmarkRepository; private final AccountRepository accountRepository; @Autowired BookmarkRestController(BookmarkRepository bookmarkRepository, AccountRepository accountRepository) { this.bookmarkRepository = bookmarkRepository; this.accountRepository = accountRepository; } @RequestMapping(method = RequestMethod.GET) Collection<Bookmark> readBookMarks(@PathVariable String userId) { this.validateUser(userId); return this.bookmarkRepository.findByAccountUsername(userId); } @RequestMapping(method = RequestMethod.POST) ResponseEntity<?> add(@PathVariable String userId, @RequestBody Bookmark input){ return this.accountRepository.findByUsername(userId).map( account -> { Bookmark result = bookmarkRepository.save(new Bookmark(account, input.uri, input.description)); URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(result.getId()).toUri(); return ResponseEntity.created(location).build(); } ).orElse(ResponseEntity.noContent().build()); } @RequestMapping(method = RequestMethod.GET, value = "/{bookmarkId}") Bookmark readBookmark(@PathVariable String userId, @PathVariable Long bookmarkId) { this.validateUser(userId); return this.bookmarkRepository.findOne(bookmarkId); } private void validateUser(String userId){ this.accountRepository.findByUsername(userId).orElseThrow(() -> new UserNotFoundException(userId)); }}
package bookmarks;import org.springframework.http.HttpStatus;import org.springframework.web.bind.annotation.ResponseStatus;/** * Created by ehang on 2016/12/31. */@ResponseStatus(HttpStatus.NOT_FOUND)class UserNotFoundException extends RuntimeException{ public UserNotFoundException(String userId) { super("could not find user '" + userId + "'."); }}
下面是对上述部分的解释:
@RestController = @Controller + @ResponseBody
@Controller
声明作为接受HttpServletRequest及HttpServletResponse的HttpServlet(服务端
更新修改数据)
@ResponseBody
本来是用来修饰method 声明其返回值被response body所包括,
在Spring 4开始也可以修饰类这一层次 指定方法具备上述行为。
@RequestBody
用来修饰method的参数表示request body
声明后的body将由HttpMessageConverter根据context type进行“解释”
这里@Autowired作用于构造函数(对参数实现自动链接)
这里validateUser函数中调用了Spring初探(九)中提到的Optional类
的orElseThrow方法,其支持使用lambda表达式抛出异常的形式,
其他相关方法的介绍可参看:
http://www.importnew.com/6675.html
这里validateUser函数中调用了Spring初探(九)中提到的Optional类
的orElseThrow方法,其支持使用lambda表达式抛出异常的形式,
其他相关方法的介绍可参看:
http://www.importnew.com/6675.html
由@RequestMapping("/{userId}/bookmarks")及@PathVariable String userId
共同指定了传入uri的userid部分作为String类型形参传入
共同指定了传入uri的userid部分作为String类型形参传入
ResponseEntity是response的包装者(wrapper)
其基本包含response headers 及status code
其基本包含response headers 及status code
JpaRepository使用save方法(接受单个entity 或容器作为参数)
ServletUriComponentsBuilder
从HttpServletRequest中抽出information的UriComponentsBuilder
其定义了诸from开头的方法都是返回特定的(需要的)ServletUriComponentsBuilder
的工厂函数。
这里所用到的 fromCurrentRequest在除了request是由RequestContextHolder得到
的情况外是与fromRequest相同的,后者是返回拷贝了诸url部分(scheme host port path
query string)Builder
从HttpServletRequest中抽出information的UriComponentsBuilder
其定义了诸from开头的方法都是返回特定的(需要的)ServletUriComponentsBuilder
的工厂函数。
这里所用到的 fromCurrentRequest在除了request是由RequestContextHolder得到
的情况外是与fromRequest相同的,后者是返回拷贝了诸url部分(scheme host port path
query string)Builder
RequestContextHolder
可以通过RequestAttribute对象来展示request的holder 当相应的继承属性被设置为true后
这个request可以被此线程生成的子线程继承
(相应的继承方法可以通过设定setRequestAttributes方法的参数完成)
可以通过RequestAttribute对象来展示request的holder 当相应的继承属性被设置为true后
这个request可以被此线程生成的子线程继承
(相应的继承方法可以通过设定setRequestAttributes方法的参数完成)
fromCurrentRequest与fromRequest的区别可以通过如下例子看到,
来源于:
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java
Spring test源码:
Ex:
来源于:
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java
Spring test源码:
Ex:
@Testpublic void fromRequest() {this.request.setRequestURI("/mvc-showcase/data/param");this.request.setQueryString("foo=123");String result = ServletUriComponentsBuilder.fromRequest(this.request).build().toUriString();assertEquals("http://localhost/mvc-showcase/data/param?foo=123", result);}@Testpublic void fromCurrentRequest() {this.request.setRequestURI("/mvc-showcase/data/param");this.request.setQueryString("foo=123");RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(this.request));try {String result = ServletUriComponentsBuilder.fromCurrentRequest().build().toUriString();assertEquals("http://localhost/mvc-showcase/data/param?foo=123", result);}finally {RequestContextHolder.resetRequestAttributes();//resetRequestAttributes() 就是setRequestAttributes(null)}}
UriComponentsBuilder path(String path)
在此Builder有的 path后面append path
在此Builder有的 path后面append path
buildAndExpand
组成UriComponents实例 replace URI template variables("/{id}") from array(result.getId())
组成UriComponents实例 replace URI template variables("/{id}") from array(result.getId())
add函数的orElse部分使用noContent()指定HttpStatus 204 no content
整个函数构建过程可以概括为使用生成URI -> create location(URI)
整个函数构建过程可以概括为使用生成URI -> create location(URI)
JPA findOne使用外键@Id寻找对象。
关于代码的解释已经比较细致了,如果还想进一步看细节可参看原文:
https://spring.io/guides/tutorials/bookmarks/
有关将上述示例表述为HAL形式的介绍可参看Spring 初探(十二)
0 0
- Spring 初探(十)(Spring RESTful web 应用)
- Spring MVC RESTFul Web Services
- 搭建spring RESTful Web Service
- Restful在Spring中的应用
- Spring 初探(九)(Spring JPA 应用实例)
- Spring Web MVC实现Restful Web Service
- Spring Web MVC实现Restful Web Service
- spring boot demo( 获取一个RESTful web service)
- 快速搭建RESTful Web Service(Spring Boot)
- Restful API设计(Java web Spring MVC 版)
- restful--spring
- Spring RESTful
- RESTful Web Services初探
- RESTful Web Services初探
- RESTful Web Services初探
- Spring restful web service编码乱码问题
- Spring restful web service编码乱码问题
- Spring restful web service编码乱码问题
- linux 9 -- 交互式使用Bash Shell
- 【工具】Phalcon devtool 官方包
- JAVA内存基本原理详解
- 符号三角形(dfs)
- android 面试题三
- Spring 初探(十)(Spring RESTful web 应用)
- 张小龙首次全面阐述小程序,定档1月9日上线(内附演讲全文)
- 使用公历类GregorianCalendar
- Celery源码分析(五)----------Consumer的Blueprint
- 聊聊HDFS BlockManager的服务化改造
- 周易六十四卦——雷火丰卦
- 摄像头常见参数解释
- Activity之间,Activity与Fragment之间传递Bitmap对象时程序崩溃的原因及解决办法
- 【Codeforces 750 B New Year and North Pole 】+ 手速