一、Controller配置方式
第一种 URL对应Bean
如果要使用此类配置方式,需要在XML中做如下样式配置
以上配置,访问/hello.do就会寻找ID为/hello.do的Bean,此类方式仅适用小型的应用系统
第二种 为URL分配Bean
使用一个统一配置集合,对各个URL对应的Controller做关系映射
此类配置还可以使用通配符,访问/hello.do时,Spring会把请求分配给helloController进行处理
第三种 URL匹配Bean
如果定义的Controller名称规范,也可以使用如下配置
第四种 注解
首先在配置文件中开启注解
在编写类上使用注解@org.springframework.stereotype.Controller标记这是个Controller对象
使用@RequestMapping("/hello.do")指定方法对应处理的路径,这里只是简单示例,会有更复杂配置
代码类如下:
spring.zip (4 MB)
二、Controller详解
获取请求输入
Spring MVC 提供三种方式来获取 client 传输的数据:
- 查询参数(Query parameters)
- 表单参数(Form parameters)
- 路径变量(Path variables)
查询参数(Query parameters)
Spring MVC 中可以通过 @RequestParam
注解获取请求中的参数,还可以通过 defaultValue
属性设置默认值(只能使用 String
类型)。
@RequestMapping(method=RequestMethod.GET) public List<Spittle> spittles( @RequestParam(value="max", defaultValue=MAX_LONG_AS_STRING) long max, @RequestParam(value="count", defaultValue="20") int count) { return spittleRepository.findSpittles(max, count); }
路径变量(Path variables)
如果需要通过 ID 查询一个资源,我们可以把 ID 放在请求参数的位置上(/spittles/show?spittle_id=12345),也可以放在路径变量的位置上(/spittles/12345)。对于一个资源来说,后一种方式要更好,前一种方式表明一个动作带有请求参数,后一种就代表我是请求一个 ID 为 12345 的资源,更明确也更简单。
为了写一个面向资源的控制器,需要使用 {
和 }
把路径变量括起来,这样 Spring 才能解析。然后,使用 @PathVariable
注解将路径变量的值赋值给一个变量,以便在控制器中使用。
@RequestMapping(value="/{spittleId}", method=RequestMethod.GET) public String spittle( @PathVariable("spittleId") long spittleId, Model model) { model.addAttribute(spittleRepository.findOne(spittleId)); return "spittle"; }
在本例中,使用了 spittleId
作为 url 上的占位符,然后赋值给 spittleId
。如果省略 @PathVariable
注解的 value
属性,那么必须保证占位符和变量名称匹配,这样才能正确解析。
表单参数
如果请求参数包含一个 bean(比如整个表单的提交),那么可以使用 Spring 自动将请求参数组合成一个 Bean。
@RequestMapping(method=RequestMethod.POST) public String saveSpittle(SpittleForm form, Model model) throws Exception { spittleRepository.save(new Spittle(null, form.getMessage(), new Date(), form.getLongitude(), form.getLatitude())); return "redirect:/spittles"; }
在 saveSpittle
方法的参数上,有个 SpittleForm
类型的参数。Spring 会用请求参数中和 SpittleForm
中成员变量相同名称的参数的值来填充 from
变量。
本例中,返回了一个 redirect:
作为前缀的字符串,当 InternalResourceViewResolver
看到这个前缀是,将会执行 redirect
动作,而不是渲染视图。当然,如果要执行 forward
只需要把前缀修改为 forward:
就行了。
表单验证
Spring 支持 Java Validation API(又叫做 JSR-303),从 Spring 3.0 开始,Spring MVC 就支持 Java Validation API。不需要任何额外的配置,需要保证项目 classpath 有 Java Validation API 的实现(比如 Hibernate Validator)就行了。
Java Validation API 定义了一些注解,可用来限制 JavaBean 中属性的值,只需要将需要的注解放在属性上就行了。这些注解所在的包为 javax.validation.constraints
,如下列出常用的:
注解 | 描述 |
---|---|
@AssertFalse |
必须为 Boolean 类型且为 false |
@AssertTure |
必须为 Boolean 类型且为 true |
@DecimalMax |
数值必须小于或等于一个给定的 BigDecimalString 值 |
@DecimalMin |
必须为数字且小于或等于一个给定的 BigDecimalString 的值 |
@Digits |
必须为数字,且值必须为给定的数值 |
@Future |
值必须为一个未来的日期 |
@Max |
必须为数字,且值小于或等于给定的值 |
@Min |
必须为数字,且值大于或等于给定的值 |
@NotNull |
不能为 null |
@Null |
必须为 null |
@Past |
值必须为一个过去的日期 |
@Pattern |
值必须满足给定的正则表达式 |
@Size |
必须为 String ,集合或数组的一种,且长度需满足给定的范围 |
要验证某个 Bean,只需在成员变量上加上需要的注解,然后在控制器上使用 @Valid
注解。
package spittr.web; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; public class SpittleForm { @NotNull @Size(min=1, max=140) private String message; @Min(-180) @Max(180) private Double longitude; @Min(-90) @Max(90) private Double latitude; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Double getLongitude() { return longitude; } public void setLongitude(Double longitude) { this.longitude = longitude; } public Double getLatitude() { return latitude; } public void setLatitude(Double latitude) { this.latitude = latitude; } }
控制器上在方法参数的 bean 上使用 @Valid
注解,Spring MVC 就会根据 bean 属性上的注解去验证 bean:
@RequestMapping(value="/register", method=POST) public String processRegistration(@Valid Spitter spitter, Errors errors) { if (errors.hasErrors()) { return "registerForm"; } spitterRepository.save(spitter); return "redirect:/spitter/" + spitter.getUsername(); }
其中,方法参数中的 Errors
标明验证的结果(注意:Errors
必须紧跟在 @Valid
注解的需验证的 bean 后面)。