【Spring实战——构建Spring Web应用程序】1.9接受请求的输入
- 有些Web应用是只读的。人们只能通过浏览器在站点上闲逛,阅读服务器发送到浏览器中的内容。
- 这并不是一成不变。众多的Web应用允许用户参与进去,将数据发送回服务器。如果没有这项能力的话,那Web将完全是另一番景象。
- Spring MVC允许以多种方式将客户端中的数据传送到控制器的处理器方法中,包括:
- 你将会看到如何编写控制器处理这些不同机制的输入。
- 作为开始,我 们先看一下如何处理带有查询参数的请求,这也是客户端往服务器端 发送数据时,最简单和最直接的方式。
5.3.1 处理查询参数
分页的Spittle列表
背景
现状
目前的SpittleController只能展示最新的Spittle,无法向前翻页查看之前的Spittle历史记录。
为了让用户能够查看某一页的Spittle历史记录,需要提供一种方式让用户传递参数,以确定要展示哪些Spittle集合。
实现分页功能的方法
为了实现这个功能,我们将程序清单5. 10中的spittles ()方法替换 为使用before和count参数的新spittles ()方法。
测试
我们首先添加 一个测试,这个测试反映了新spittles ()方法的功能。
第一个测试,传入max和count
程序清单5.11 用来测试分页Spittle 列表的新方法
这个测试方法与程序清单5.9中的测试方法关键区别在于它针对“/spittles”发送GET请求,同时还传入了max和count参数。它测试了这些参数存在时的处理器方法.
而另一个测试方法则测试了没有这些参数时的情景。这两个测试就绪后,我们就能确保不管控制器发生什么样的变化,它都能够处理这两种类型的请求。
第二个测试,对无参数和没有参数情况
在SpittleController中的处理器方法需要同时处理有参数和没有参数的情况。因此,我们需要对其进行修改,使其能够接受参数。
第三个测试,请求参数不存在设置默认值
同时,如果这些参数在请求中不存在,我们将使用默认值Long.MAX_VALUE和20。为了实现这一目标,我们可以使用@RequestParam注解的defaultValue属性。
如果没有指定max参数,它将默认为Long类型的最大值。由于查询参数都是String类型的,所以defaultValue属性需要一个String类型的值。
因此,我们可以将Long.MAX_VALUE转换为一个名为MAX_LONG_AS_STRING的String类型常量。
尽管defaultValue属性给定的是String类型的值,但是当绑定到方法的max参数时,它会转换为Long类型。
如果请求中没有count参数的话,count参数的默认值将会设置为20。
请求中的查询参数是往控制器中传递信息的常用手段。另外一种方式也很流行,尤其是在构建面向资源的控制器时,这种方式就是将传递参数作为请求路径的一部分。
让我们看一下如何将路径变量作为请求路径的一部分,从而实现信息的输入。
5.3.2 通过路径参数接受输入
假设我们的应用程序需要根据给定的ID来展现某一个Spittle记录。
方案一:编写处理器方法,使用@RequestParam注解
让它接受ID作为查询参数:
处理器请求方式: 如"/spittles/show?spittle_id=12345"
优点:虽然这种方式可以正常工作,但从面向资源的角度来看,并不理想。
面向资源的理想情况:理想情况,要识别的资源(Spittle)应该通过URL路径进行进行标识,而不是通过查询参数。
URL路径:"/spittles/12345" 或"/spittles/show?spittle_id=12345"
URL路径标识资源的优势:通过URL路径来标识资源能更好地识别要查询的资源。
查询参数的方式:带有参数的操作,本质是通过HTTP发起的RPC。
将需求转换为测试:既然已经以面向资源的控制器作为目标,我们可以将这个需求转换为一个测试。
程序清单5.12展示了一个新的测试方法,它会断言SpittleController中对面向资源请求的处理。
程序清单5.12 测试对某个Spittle 的请求,其中ID要在路径变量中 指定
测试结果:因为没有为这个请求实现处理器方法,所以请求会失败。
方案二:使用@RequestMapping占位符
但是,我们可以通过为SpittleController添加新的方法来修正这个失败的测试。 对代码进行改造。
- 路径变量的实现:到目前为止,我们编写的控制器中的所有方法都映射到静态定义好的路径上(通过@RequestMapping)。但是,为了使测试通过,我们需要在@RequestMapping路径中包含变量部分,这部分代表了Spittle的ID。
- 占位符的使用:为了实现路径变量,Spring MVC允许在@RequestMapping路径中添加占位符,占位符的名称要用大括号("{“和”}")括起来。路径中的其他部分要与所处理的请求完全匹配,但是占位符部分可以是任意的值。
下面的处理器方法使用了占位符,将Spittle ID作为路径的一部 分:
通过程序清单5.12中的路径,可以看到控制器可以处理针对“/spittles/12345”的请求。
方案三:使用@PathVariable注解
功能:添加@PathVariable注解,无论占位符是什么,都会传递到处理器方法中的spittleId参数中。
示例说明:例如,如果向"/spittles/54321"发送GET请求,将把"54321"作为spittleId的值传递进来。
参数名与占位符的对应:由于方法的参数名与占位符的名称相同,因此可以省略@PathVariable中的value属性。
- @PathVariable注解的默认行为:如果在@PathVariable注解中没有指定value属性,它会假设占位符的名称与方法的参数名相同。这样可以使代码更简洁,因为不需要重复写占位符的名称。
- 重命名参数的注意事项:但需要注意的是,如果想要重命名参数,必须同时修改占位符的名称,使它们匹配。
- spittle()方法的功能:
这个视图并没有什么特别之处,它的屏幕截图如图5.4所示。
图5 .4 在浏览器中展现一个spittle
如果传递请求中少量的数据,那查询参数和路径变量是很合适的。但 通常我们还需要传递很多的数据 (也许是表单提交的数据) ,那查询 参数显得有些笨拙和受限了。下面让我们来看一下如何编写控制器方 法来处理表单提交。
共同学习,写下你的评论
评论加载中...
作者其他优质文章