使用RESTful风格开发JavaWeb_第1页
使用RESTful风格开发JavaWeb_第2页
使用RESTful风格开发JavaWeb_第3页
使用RESTful风格开发JavaWeb_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、使RESTful风格开发JavaWeb什么是RESTful风格?REST是REpresentational State Transfer的缩写(般中翻译为表述性状态转移),REST是种体系结构,HTTP是种包含了 REST架构属性的协议,为了便于理解,我们把它的字母拆分成不同的个部分:表述性(REpresentational): REST资源实际上可以各种形式来进表述,包括XML、JSON甚 HTML最适合资源使者的任意形式;状态(State): 当使 REST的时候,我们更关注资源的状态不是对资源采取的为;转义(Transfer): REST涉及到转移资源数据,它以某种表述性形式从个应转移到

2、另个应。简单地说,REST就是将资源的状态以适合客户端或服务端的形式从服务端转移到客户端(或者反过来)。在REST中,资源通过 URL 进识别和定位,然后通过为(即 HTTP法)来定义 REST来完成怎样的功能。实例说明:在平时的 Web开发中,method 常的值是 GET和 POST,但是实际上,HTTP法还有 PATCH、DELETE、PUT等其他值,这些法通常会匹配为如下的CRUD 动作: 或 尽管通常来讲,HTTP法会映射为 CRUD 动作,但这并不是严格的限制,有时候PUT也可以来创建新的资源,POST也可以来更新资源。实际上,POST请求幂等的特性(即同个 URL 可以得到不同的

3、结果)使其成个常灵活地法,对于法适应其他HTTP法语义的操作,它都能够胜任。在使 RESTful风格之前,我们如果想要增加条商品数据通常是这样的:/addCategory?name=xxx但是使了 RESTful风格之后就会变成:/category这就变成了使同个URL ,通过约定不同的HTTP法来实施不同的业务,这就是RESTful风格所做的事情了,为了有个更加直观的理解,引下来的图:SpringBoot中使 RESTfulRESTful API具体设计如下:User实体定义:public class User private Long id;private String name;priv

4、ate Integer age;/省略setter和getter实现对User对象的操作接RestControllerRequestMapping(value=/users) / 通过这配置使下的映射都在/users下public class UserController /创建线程安全的Mapstatic Map users = Collections.synchronizedMap(new HashMap();RequestMapping(value=/, method=RequestMethod.GET)public List getUserList() /处理/users/的GET请求

5、,来获取户列表/还可以通过RequestParam从页中传递参数来进查询条件或者翻页信息的传递List r = new ArrayList(users.values();return r;RequestMapping(value=/, method=RequestMethod.POST)public String postUser(ModelAttribute User user) /处理/users/的POST请求,来创建User/除了ModelAttribute绑定参数之外,还可以通过RequestParam从页中传递参数users.put(user.getId(), user);retu

6、rn success;RequestMapping(value=/id, method=RequestMethod.GET)public User getUser(PathVariable Long id) /处理/users/id的GET请求,来获取url中id值的User信息/ url 的id可通过PathVariable绑定到函数的参数中return users.get(id);RequestMapping(value=/id, method=RequestMethod.PUT)public String putUser(PathVariable Long id, ModelAttrib

7、ute User user) /处理/users/id的PUT请求,来更新User信息User u = users.get(id);u.setName(user.getName();u.setAge(user.getAge();users.put(id, u);return success;RequestMapping(value=/id, method=RequestMethod.DELETE)public String deleteUser(PathVariable Long id) /处理/users/id的DELETE请求,来删除Userusers.remove(id);return

8、success;编写测试单元下针对该Controller编写测试例验证正确性,具体如下。当然也可以通过浏览器插件等进请求提交验证,因为涉及些包的导,这给出全部代码:package cn.wmyskxz.springboot;import cn.wmyskxz.springboot.controller.UserController;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.boot.test.context.SpringBoot

9、Test;import org.springframework.mock.web.MockServletContext;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import org.springframework.test.context.web.WebAppConfiguration;import org.springframework.test.web.servlet.MockMvc;import org.springframework.test.web.servlet.RequestBu

10、ilder;import org.springframework.test.web.servlet.setup.MockMvcBuilders;import static org.hamcrest.Matchers.equalTo;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;import stati

11、c org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;/* author: 我没有三颗脏* create: 2018-05-29-上午 8:39*/RunWith(SpringJUnit4ClassRunner.class)SpringBootTest(classes = MockServletContext.class)WebAppConfigurationpublic class ApplicationTests private MockMvc mvc;Beforepublic void set

12、Up() throws Exception mvc = MockMvcBuilders.standaloneSetup(new UserController().build();Testpublic void testUserController() throws Exception /测试UserControllerRequestBuilder request = null;/ 、get查下user列表,应该为空request = get(/users/);mvc.perform(request).andExpect(status().isOk().andExpect(content().s

13、tring(equalTo();/ 、post提交个userrequest = post(/users/).param(id, 1).param(name, 测试师).param(age, 20);mvc.perform(request).andExpect(content().string(equalTo(success);/ 、get获取user列表,应该有刚才插的数据request = get(/users/);mvc.perform(request).andExpect(status().isOk().andExpect(content().string(equalTo(id:1,na

14、me:测试师,age:20);/ 、put修改id为1的userrequest = put(/users/1).param(name, 测试终极师).param(age, 30);mvc.perform(request).andExpect(content().string(equalTo(success);/ 、get个id为1的userrequest = get(/users/1);mvc.perform(request).andExpect(content().string(equalTo(id:1,name:测试终极师,age:30);/ 、del删除id为1的userrequest

15、= delete(/users/1);mvc.perform(request).andExpect(content().string(equalTo(success);/ 、get查下user列表,应该为空request = get(/users/);mvc.perform(request).andExpect(status().isOk().andExpect(content().string(equalTo();MockMvc实现了对HTTP请求的模拟,从例的代码就能够看出MockMvc的简单法,它能够直接使络的形式,转换到Controller的调,这样使得测试速度快、不依赖络环境,且提供

16、了套验证的具,这样可以使得请求的验证统且很便。需要注意的就是在MockMvc使之前需要先MockMvcBuilders构建MockMvc对象,如果对单元测试感兴趣的童鞋请戳上的链接哦,这就不细说了测试信息运测试类,控制台返回的信息如下:_/ / _/ / _ _ _ _ _ / _ _ _ / _ _/ / /,_ , /_/ /_/_/_/ /_/_/_/2018-05-29 09:28:18.730 INFO 5884 - 2018-05-29 09:28:18.735 INFO 5884 - 2018-05-29 09:28:18.831 INFO 5884 - 2018-05-29 0

17、9:28:19.200 INFO 5884 - 2018-05-29 09:28:19.798 INFO 5884 - main cn.wmyskxz.springboot.ApplicationTests : Starting ApplicationTests on SC-201803262103 with PID 5884 (started by Administrator in E:Java Projectsspringboot)main cn.wmyskxz.springboot.ApplicationTests : No active profile set, falling bac

18、k to default profiles: defaultmain o.s.w.c.s.GenericWebApplicationContext : Refreshing org.springframework.web.context.support.GenericWebApplicationContext7c37508a: startup date Tue May 29 09:28:18 CST 2018; root of context himain cn.wmyskxz.springboot.ApplicationTests : Started ApplicationTests in

19、1.184 seconds (JVM running for 2.413)main s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped /users/id,methods=PUT onto public java.lang.String cn.wmyskxz.springboot.controller.UserController.putUser(java.lang.Long,cn.wmyskxz.spr2018-05-29 09:28:19.800 INFO 5884 - 2018-05-29 09:28:19.800 INFO 5884 -

20、2018-05-29 09:28:19.801 INFO 5884 - 2018-05-29 09:28:19.801 INFO 5884 - 2018-05-29 09:28:19.850 INFO 5884 - 2018-05-29 09:28:19.924 INFO 5884 - 2018-05-29 09:28:19.925 INFO 5884 - 2018-05-29 09:28:19.926 INFO 5884 - main s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped /users/,methods=GET onto publ

21、ic java.util.List cn.wmyskxz.springboot.controller.UserControllermain s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped /users/,methods=POST onto public java.lang.String cn.wmyskxz.springboot.controller.UserController.postUser(cn.wmyskxz.springboot.pojo.Usemain s.w.s.m.m.a.RequestMappingHandlerMappi

22、ng : Mapped /users/id,methods=DELETE onto public java.lang.String cn.wmyskxz.springboot.controller.UserController.deleteUser(java.lang.Long)main s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped /users/id,methods=GET onto public cn.wmyskxz.springboot.pojo.User cn.wmyskxz.springboot.controller.UserCo

23、ntroller.getUser(java.lang.Lonmain s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for ControllerAdvice: org.springframework.test.web.servlet.setup.StubWebApplicationContext42f8285emain o.s.mock.web.MockServletContext: Initializing Spring FrameworkServlet main o.s.t.web.servlet.TestDispatcherServ

24、let : FrameworkServlet : initialization startedmain o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet : initialization completed in 1 ms通过控制台信息,我们得知通过RESTful风格能成功调到正确的法并且能获取到或者返回正确的参数,没有任何错误,则说明成功!如果你想要看到更多的细节信息,可以在每次调perform() 法后再跟上句.andDo(MockMvcResultHandlers.print() ,例如:/ 、get查下user列表,应

25、该为空request = get(/users/);mvc.perform(request).andExpect(status().isOk().andExpect(content().string(equalTo().andDo(MockMvcResultHandlers.print();就能看到详细的信息,就像下这样:MockHttpServletRequest:HTTP Method = GETRequest URI= /users/Parameters = Headers = Body = Session Attrs = Handler:Type = cn.wmyskxz.spring

26、boot.controller.UserControllerMethod = public java.util.List cn.wmyskxz.springboot.controller.UserController.getUserList()Async:Async started = falseAsync result = nullResolved Exception:Type = nullModelAndView:View name = nullView = nullModel= nullFlashMap:Attributes = nullMockHttpServletResponse:S

27、tatus = 200Error message = nullHeaders = Content-Type=application/json;charset=UTF-8Content type = application/json;charset=UTF-8Body = Forwarded URL = nullRedirected URL = nullCookies = 总结我们仍然使 RequestMapping 注解,但不同的是,我们指定method 属性来处理不同的HTTP法,并且通过PathVariable 注解来将 HTTP请求中的属性绑定到我们指定的形参上。事实上,Spring 4

28、.3 之后,为了更好的持RESTful风格,增加了个注解:PutMapping、GetMapping、DeleteMapping、PostMapping,从名字也能概的看出,其实也就是将method 属性的值与 RequestMapping进了绑定已,例如,我们对UserController中的deleteUser法进改造:-改造前-RequestMapping(value=/id, method=RequestMethod.DELETE)public String deleteUser(PathVariable Long id) /处理/users/id的DELETE请求,来删除Userus

29、ers.remove(id);return success;-改造后-DeleteMapping(/id)public String deleteUser(PathVariable Long id) /处理/users/id的DELETE请求,来删除Userusers.remove(id);return success;使Swagger2构造RESTful API档RESTful 风格为后台与前台的交互提供了简洁的接API,并且有利于减少与其他团队的沟通成本,通常情况下,我们会创建份RESTful API档来记录所有的接细节,但是这样做有以下的个问题:由于接众多,并且细节复杂(需要考虑不同的H

30、TTP请求类型、HTTP头部信息、HTTP请求内容等),质量地创建这份档本就是件常吃的事,下游的抱怨声不绝于。随着时间推移,不断修改接实现的时候都必须同步修改接档,档与代码处于两个不同的媒介,除有严格的管理机制,不然很容易导致不致现象。Swagger2的出现就是为了解决上述的这些问题,并且能够轻松的整合到我们的SpringBoot中去,它既可以减少我们创建档的作量,同时说明内容可以整合到代码之中去,让维护档和修改代码整合为体,可以让我们在修改代码逻辑的同时便的修改档说明,这太酷了,另外Swagger2页提供了强的页测试功能来调试每个RESTful API,具体效果如下:让我们赶紧来看看吧:第步

31、:添加Swagger2依赖:在 pom.xml 中加Swagger2的依赖:io.springfoxspringfox-swagger22.2.2io.springfoxspringfox-swagger-ui2.2.2第步:创建Swagger2配置类在SpringBoot启动类的同级录下创建Swagger2的配置类 Swagger2:ConfigurationEnableSwagger2public class Swagger2 Beanpublic Docket createRestApi() return new Docket(DocumentationType.SWAGGER_2).a

32、piInfo(apiInfo().select().apis(RequestHandlerSelectors.basePackage(cn.wmyskxz.springboot).paths(PathSelectors.any().build();private ApiInfo apiInfo() return new ApiInfoBuilder().title(Spring Boot中使Swagger2构建RESTful APIs).description(原地址链接:/springbootswagger2/).termsOfServiceUrl(/).contact(我没有三颗脏).ve

33、rsion(1.0).build();如上的代码所,通过Configuration 注解让Spring来加载该配置类,再通过EnableSwagger2 注解来启动Swagger2;再通过 createRestApi 函数创建 Docket 的Bean之后,apiInfo() 来创建该API的基本信息(这些基本信息会展现在档页中),select() 函数返回个 ApiSelectorBuilder 实例来控制哪些接暴露给Swagger来展现,本例采指定扫描的包路径来定义,Swagger会扫描该包下所有的Controller定义的API,并产档内容(除了被ApiIgnore 指定的请求)第三步:

34、添加档内容在完成了上述配置后,其实已经可以产档内容,但是这样的档主要针对请求本,描述主要来源于函数等命名产,对户并不友好,我们通常需要增加些说明来丰富档内容。如下所,我们通过ApiOperation注解来给API增加说明、通过ApiImplicitParams、ApiImplicitParam注解来给参数增加说明。RestControllerRequestMapping(value=/users) / 通过这配置使下的映射都在/users下,可去除public class UserController static Map users = Collections.synchronizedMap

35、(new HashMap();ApiOperation(value=获取户列表, notes=)RequestMapping(value=, method=RequestMethod.GET)public List getUserList() List r = new ArrayList(users.values();return r;ApiOperation(value=创建户, notes=根据User对象创建户)ApiImplicitParam(name = user, value = 户详细实体user, required = true, dataType = User)RequestMapping(value=, method=RequestMethod.POST)public String postUser(RequestBody User user) users.put(user.getId(), user);return success;ApiOperation(value=获取户详细信息

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论