笔记27 接受请求的输入 ——通过路径参数接受输入

假设我们的应用程序需要根据给定的ID来展现某一个Spittle记 录。其中一种方案就是编写处理器方法,通过使用@RequestParam 注解,让它接受ID作为查询参数:

1     @RequestMapping(value = "/spittle", method = RequestMethod.GET)
2     public String showSpittle(@RequestParam("spittle_id") long spittleId, Model model) {
3         model.addAllAttributes(spittleRepository.findOne(spittleId));
4         return "spittle";
5     }

这个处理器方法将会处理形如“/spittles?spittle_id=12345”这样的 请求。尽管这也可以正常工作,但是从面向资源的角度来看这并不理 想。在理想情况下,要识别的资源(Spittle)应该通过URL路径进 行标示,而不是通过查询参数。对“/spittles/12345”发起GET请求要优 于对“/spittles?spittle_id=12345”发起请求。前者能够识别出要查 询的资源,而后者描述的是带有参数的一个操作——本质上是通过 HTTP发起的RPC。

1.修改测试方法:其中ID要在路径变量中 指定

 1     private List<Spittle> createSpittleList(int count) {
 2         List<Spittle> spittles = new ArrayList<Spittle>();
 3         for (int i = 0; i < count; i++) {
 4             spittles.add(new Spittle("Spittle" + i, new Date()));
 5         }
 6         return spittles;
 7     }
 8 
 9     @Test
10     public void testSpittle() throws Exception {
11 
12         Spittle spittle = new Spittle("hello", new Date());
13 
14         List<Spittle> expectedSpittle = new ArrayList<Spittle>();
15         expectedSpittle.add(spittle);
16         SpittleRepository mockRepository = mock(SpittleRepository.class);
17         when(mockRepository.findOne(12345)).thenReturn(expectedSpittle);
18 
19         SpittleController controller = new SpittleController(mockRepository);
20 
21         MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
22 
23         mockMvc.perform(get("/spittles/12345")).andExpect(view().name("spittle"))
24                 .andExpect(model().attributeExists("spittleList"))
25                 .andExpect(model().attribute("spittleList", hasItems(expectedSpittle.toArray())));
26 
27     }

这个测试构建了一个mockRepository、一个控制器和 MockMvc,这与本章中我们所编写的其他测试很类似。这个测试中 最重要的部分是最后几行,它对“/spittles/12345”发起GET请求,然后 断言视图的名称是spittleList,并且预期的expectedSpittle对象放到了模型之中。

2.在SpittleController添加新的方法

1     @RequestMapping(value = "/{spittleId}", method = RequestMethod.GET)
2     public String showSpittle(@PathVariable("spittleId") long spittleId, Model model) {
3         model.addAttribute("spittleList", spittleRepository.findOne(spittleId));
4         return "spittle";
5     }

在@RequestMapping 路径中添加占位符。占位符的名称要用大括号(“{”和“}”)括起来。 路径中的其他部分要与所处理的请求完全匹配,但是占位符部分可以 是任意的值。

在showSpittle()方法的spittleId参数上添加了 @PathVariable("spittleId")注解,这表明在请求路径中,不 管占位符部分的值是什么都会传递到处理器方法的spittleId参数中。如果对“/spittles/54321”发送GET请求,那么将会把“54321”传递进 来,作为spittleId的值。 

注:如果@PathVariable中没有value属性的话,它会假设占位符的名 称与方法的参数名相同。

showSpittle()方法会将参数传递到SpittleRepository的 findOne()方法中,用来获取某个Spittle对象,然后将Spittle 对象添加到模型中。

1 List<Spittle> findOne(long spittleId);

3.spittle.jsp用于展示查询的spittle

 1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 2 <html>
 3   <head>
 4     <title>Spitter</title>
 5     <link rel="stylesheet" 
 6           type="text/css" 
 7           href="<c:url value="/resources/style.css" />" >
 8   </head>
 9   <body>
10   <c:forEach items="${spittleList}" var="spittles" >
11     <div class="spittleView">
12       <div class="spittleMessage"><c:out value="${spittles.message}" /></div>
13       <div>
14         <span class="spittleTime"><c:out value="${spittles.time}" /></span>
15       </div>
16     </div>
17     </c:forEach>
18   </body>
19 </html>

 4.测试

posted @ 2018-04-24 22:34  雨落忧伤-  阅读(238)  评论(0编辑  收藏  举报