Spring 初探(十)(Spring RESTful web 应用)
2017-01-01 13:12
295 查看
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的方法对待
下面来看一个示例部分代码:
Ex:
下面是对上述部分的解释:
@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
由@RequestMapping("/{userId}/bookmarks")及@PathVariable String userId
共同指定了传入uri的userid部分作为String类型形参传入
ResponseEntity是response的包装者(wrapper)
其基本包含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
RequestContextHolder
可以通过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:
UriComponentsBuilder path(String path)
在此Builder有的 path后面append path
buildAndExpand
组成UriComponents实例 replace URI template variables("/{id}") from array(result.getId())
add函数的orElse部分使用noContent()指定HttpStatus 204 no content
整个函数构建过程可以概括为使用生成URI -> create location(URI)
JPA findOne使用外键@Id寻找对象。
关于代码的解释已经比较细致了,如果还想进一步看细节可参看原文: https://spring.io/guides/tutorials/bookmarks/
有关将上述示例表述为HAL形式的介绍可参看Spring 初探(十二)
有关增删改查的工作 如对于关注的对象的存取及删除都是可以进行的。
下面的部分使用了Spring 初探(九)的示例代码 搭建Spring RESTful web 的简单示例应用
先对一些基本概念进行
简要介绍。
HTTP具有如下方法来操作数据交互:
GET 不在request中设定body而返回body
DELETE remove URI做指定的资源
PUT update URI所指定的资源 使用需要发送GET所得到的类似结果
POST add or append URI所指定的资源 也可能被类似PUT的方法对待
下面来看一个示例部分代码:
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
由@RequestMapping("/{userId}/bookmarks")及@PathVariable String userId
共同指定了传入uri的userid部分作为String类型形参传入
ResponseEntity是response的包装者(wrapper)
其基本包含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
RequestContextHolder
可以通过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:
@Test public 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); } @Test public 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
buildAndExpand
组成UriComponents实例 replace URI template variables("/{id}") from array(result.getId())
add函数的orElse部分使用noContent()指定HttpStatus 204 no content
整个函数构建过程可以概括为使用生成URI -> create location(URI)
JPA findOne使用外键@Id寻找对象。
关于代码的解释已经比较细致了,如果还想进一步看细节可参看原文: https://spring.io/guides/tutorials/bookmarks/
有关将上述示例表述为HAL形式的介绍可参看Spring 初探(十二)
相关文章推荐
- Webcollector + Spring + MVC 搭建应用初探(二)
- Webcollector + Spring + MVC 搭建应用初探(四)
- Webcollector + Spring + MVC 搭建应用初探(一)
- Webcollector + Spring + MVC 搭建应用初探(三)
- Webcollector + Spring + MVC 搭建应用初探(六)(Lenskit 推荐系统实例)
- Webcollector + Spring + MVC 搭建应用初探(五)(Crab 推荐系统实例)
- struts+spring+hibernate的web应用 Web层代码编写(1)
- struts+spring+hibernate的web应用 架构搭建
- struts+spring+hibernate的web应用 Dao层代码编写
- struts+spring+hibernate的web应用 Service层代码编写
- WEB应用通过Spring注入实现类
- spring入门及web下应用环境的初始化(lp)
- CZTZ-JavaEE开源应用开发平台介绍之二(Webwork+spring+hbernate+acegi)
- WEB开发中Spring AOP实际应用一例
- Spring Web应用入门
- 基于Spring 2.0的Web应用设计
- struts+spring+hibernate的web应用 Dao层代码编写
- struts+spring+hibernate的web应用 架构搭建
- 使用JSF, Spring, Hibernate构建一个实际的web应用(转载)
- struts+spring+hibernate的web应用 Web层代码编写(2)