默认情况下,spring mvc的数据映射的实现是自动查找请求中的key为参数名的parameter的值。比如有以下方法:
@RequestMapping(value="/xml", method=RequestMethod.POST) public String xmlData(String name, Integer age){ System.out.println(name+" "+age); return "/index"; }
则Spring MVC会使用如下的方法给参数注入值:
name = request.getParameter("name"); age= new Integer(request.getParameter("age"));
如果想要实现一些自定义的解析方式,又该如何做呢?
Spring提供了一个annotation org.springframework.web.bind.annotation.InitBinder 可以用来做一些简单的、自定义的解析的实现。
例如请求内容如下:
<a> <name>sss</name> <age>21</age> </a>
这里希望解析完以后,方法中的参数name和age就是对应的xml内容中的name和age的元素的值。
首先定义一个添加了 InitBinder 注解的方法:
@InitBinder public void addBinder(WebDataBinder webDataBinder, WebRequest webRequest){ 。。。 }
根据InitBinder的文档说明,以它注解的方法上可以添加很多参数(同RequestMapping) ,典型的参数就是上面看到的WebDataBinder和WebRequest。
由于需要的参数类型分别是String和Integer,所以这里添加对于String和Integer类型的自定义的解析的支持,如下:
@InitBinder public void addBinder(WebDataBinder webDataBinder, WebRequest webRequest){ webDataBinder.registerCustomEditor(String.class, new CustomPropertyEditor(webDataBinder.getObjectName(), webRequest)); webDataBinder.registerCustomEditor(Integer.class, new CustomPropertyEditor(webDataBinder.getObjectName(), webRequest)); }
这里 webDataBinder.getObjectName() 里取出来的值就分别是name和age,根据参数的个数,这个方法会被调用多次。
下面就是CustomPropertyEditor的实现了:
public class CustomPropertyEditor extends PropertyEditorSupport { private WebRequest WebRequest; private String objectName; private String value; public CustomPropertyEditor(String objectName, WebRequest webRequest) { super(); WebRequest = webRequest; this.objectName = objectName; extractXML(); } private void extractXML() { String xmlContent = WebRequest.getParameter("xml"); if(xmlContent != null){ try { DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); ByteArrayInputStream inputStream = new ByteArrayInputStream(xmlContent.getBytes()); Document document = documentBuilder.parse(inputStream); NodeList elementsByTagName = document.getElementsByTagName(objectName); if(elementsByTagName != null && elementsByTagName.getLength() > 0){ value = elementsByTagName.item(0).getTextContent(); } } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } } @Override public Object getValue() { return value; } }
这里就是简单的提取xml中的内容,然后把提供的内容作为getValue()方法的返回值输出就可以了。