基于Spring MVC的Web应用开发(8) - Convert
本文介绍SpringMVC中的Convert,Convert是我认为的SpringMVC最吸引人,最优雅的特性,下面通过例子程序领略一下:
package org.springframework.samples.mvc.convert; import java.util.Collection; import java.util.Date; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat.ISO; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/convert/*") public class ConvertController { @RequestMapping("primitive") public @ResponseBody String primitive(@RequestParam Integer value) { return "Converted primitive " + value; } // requires Joda-Time on the classpath @RequestMapping("date/{value}") public @ResponseBody String date(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date value) { return "Converted date " + value; } @RequestMapping("collection") public @ResponseBody String collection(@RequestParam Collection<Integer> values) { return "Converted collection " + values; } @RequestMapping("formattedCollection") public @ResponseBody String formattedCollection(@RequestParam @DateTimeFormat(iso=ISO.DATE) Collection<Date> values) { return "Converted formatted collection " + values; } @RequestMapping("bean") public @ResponseBody String bean(JavaBean bean) { return "Converted " + bean; } @RequestMapping("value") public @ResponseBody String valueObject(@RequestParam SocialSecurityNumber value) { return "Converted value object " + value; } @RequestMapping("custom") public @ResponseBody String customConverter(@RequestParam @MaskFormat("###-##-####") String value) { return "Converted '" + value + "' with a custom converter"; } }
package org.springframework.samples.mvc.convert; import java.util.Collection; import java.util.Date; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat.ISO; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/convert/*") public class ConvertController { @RequestMapping("primitive") public @ResponseBody String primitive(@RequestParam Integer value) { return "Converted primitive " + value; } // requires Joda-Time on the classpath @RequestMapping("date/{value}") public @ResponseBody String date(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date value) { return "Converted date " + value; } @RequestMapping("collection") public @ResponseBody String collection(@RequestParam Collection<Integer> values) { return "Converted collection " + values; } @RequestMapping("formattedCollection") public @ResponseBody String formattedCollection(@RequestParam @DateTimeFormat(iso=ISO.DATE) Collection<Date> values) { return "Converted formatted collection " + values; } @RequestMapping("bean") public @ResponseBody String bean(JavaBean bean) { return "Converted " + bean; } @RequestMapping("value") public @ResponseBody String valueObject(@RequestParam SocialSecurityNumber value) { return "Converted value object " + value; } @RequestMapping("custom") public @ResponseBody String customConverter(@RequestParam @MaskFormat("###-##-####") String value) { return "Converted '" + value + "' with a custom converter"; } }
逐一方法看过来:
1.
@RequestMapping("primitive") public @ResponseBody String primitive(@RequestParam Integer value) { return "Converted primitive " + value; }
@RequestMapping("primitive") public @ResponseBody String primitive(@RequestParam Integer value) { return "Converted primitive " + value; }
@RequestParam自动获取URL提交的参数名为value的值并赋值到Integer value变量,
访问"http://localhost:8080/web/convert/primitive?value=1"
浏览器显示"Converted primitive 1"
2.
// requires Joda-Time on the classpath @RequestMapping("date/{value}") public @ResponseBody String date(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date value) { return "Converted date " + value; }
// requires Joda-Time on the classpath @RequestMapping("date/{value}") public @ResponseBody String date(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date value) { return "Converted date " + value; }
@PathVariable自动获取URL路径中date/后面的值,判断该值是否满足ISO.DATE的类型(yyyy-MM-dd),最后将这个字符串转成Date value,
访问"http://localhost:8080/web/convert/date/2012-03-30"
浏览器显示"Converted date Fri Mar 30 00:00:00 CST 2012"
3.
@RequestMapping("collection") public @ResponseBody String collection(@RequestParam Collection<Integer> values) { return "Converted collection " + values; }
@RequestMapping("collection") public @ResponseBody String collection(@RequestParam Collection<Integer> values) { return "Converted collection " + values; }
如果提交了同名参数的多个值(例如html的多选框),这些值会自动的封装到Collection<Integer> values里,
访问"http://localhost:8080/web/convert/collection?values=1&values=2"
浏览器显示"Converted collection [1, 2]"
4.
@RequestMapping("formattedCollection") public @ResponseBody String formattedCollection(@RequestParam @DateTimeFormat(iso=ISO.DATE) Collection<Date> values) { return "Converted formatted collection " + values; }
@RequestMapping("formattedCollection") public @ResponseBody String formattedCollection(@RequestParam @DateTimeFormat(iso=ISO.DATE) Collection<Date> values) { return "Converted formatted collection " + values; }
访问"http://localhost:8080/web/convert/formattedCollection?values=2012-03-30&values=2012-12-25"
浏览器显示"Converted formatted collection [Fri Mar 30 00:00:00 CST 2012, Tue Dec 25 00:00:00 CST 2012]"
以上说的都是convert简单类型,下面讲解如何convert自定义的Java类,写一个JavaBean类,该类有几个属性:
private Integer primitive; @DateTimeFormat(iso=ISO.DATE) private Date date; @MaskFormat("(###) ###-####") private String masked; // list will auto-grow as its dereferenced e.g. list[0]=value private List<Integer> list; // annotation type conversion rule will be applied to each list element @DateTimeFormat(iso=ISO.DATE) private List<Date> formattedList; // map will auto-grow as its dereferenced e.g. map[key]=value private Map<Integer, String> map; // nested will be set when it is referenced e.g. nested.foo=value private NestedBean nested;
private Integer primitive; @DateTimeFormat(iso=ISO.DATE) private Date date; @MaskFormat("(###) ###-####") private String masked; // list will auto-grow as its dereferenced e.g. list[0]=value private List<Integer> list; // annotation type conversion rule will be applied to each list element @DateTimeFormat(iso=ISO.DATE) private List<Date> formattedList; // map will auto-grow as its dereferenced e.g. map[key]=value private Map<Integer, String> map; // nested will be set when it is referenced e.g. nested.foo=value private NestedBean nested;
注意到该JavaBean还嵌套了一个自定义的Java类NestedBean,该类的属性为:
private String foo; private List<NestedBean> list; private Map<String, NestedBean> map;
private String foo; private List<NestedBean> list; private Map<String, NestedBean> map;
看一下详细用法:
5.
访问"http://localhost:8080/web/convert/bean?primitive=1"
浏览器显示"Converted JavaBean primitive=1"
6.
访问"http://localhost:8080/web/convert/bean?date=2012-03-30"
浏览器显示"Converted JavaBean date=Fri Mar 30 00:00:00 CST 2012"
7.
访问"http://localhost:8080/web/convert/bean?masked=(123)-456-7890"
浏览器显示"Converted JavaBean masked=(123) 456-7890"
8.
访问"http://localhost:8080/web/convert/bean?list[0]=1&list[1]=2"
浏览器显示"Converted JavaBean list=[1, 2]"
9.
访问"http://localhost:8080/web/convert/bean?formattedList[0]=2012-03-30&formattedList[1]=2012-12-25"
浏览器显示"Converted JavaBean formattedList=[Fri Mar 30 00:00:00 CST 2012, Tue Dec 25 00:00:00 CST 2012]"
10.
访问"http://localhost:8080/web/convert/bean?map[1]=a&map[2]=b"
浏览器显示"Converted JavaBean map={1=a, 2=b}"
11.
访问"http://localhost:8080/web/convert/bean?nested.foo=stephansun"
浏览器显示"Converted JavaBean nested=NestedBean foo=stephansun"
12.
访问"http://localhost:8080/web/convert/bean?nested.list[0].foo=stephansun"
浏览器显示"Converted JavaBean nested=NestedBean list=[NestedBean foo=stephansun]"
13.
访问"http://localhost:8080/web/convert/bean?nested.map[1].foo=stephansun"
浏览器显示"Converted JavaBean nested=NestedBean map={1=NestedBean foo=stephansun}"
14.
访问"http://localhost:8080/web/convert/value?value=1"
浏览器显示"Converted value object SocialSecurityNumber [value=1]"
15.
访问"http://localhost:8080/web/convert/custom?value=ab-cd-efgh"
浏览器显示"Converted 'ab-cd-efgh' with a custom converter"