1. 下列插件实现了包含有xml的请求body的自定义绑定。
 
public class JAXBBinderPlugin extends PlayPlugin {
 
     public static JAXBContext jc;
 
     /* (非 Javadoc)
      *  @see play.PlayPlugin#onApplicationStart()
      */
     public void onApplicationStart() {
         Logger.info("ApiPlugin loaded");
         try {
             List<ApplicationClass> applicationClasses = Play.classes.getAnnotatedClasses(XmlRootElement.class);
             List<Class> classes = new ArrayList<Class>();
             for (ApplicationClass applicationClass : applicationClasses) {
                 classes.add(applicationClass.javaClass);
             }
             jc = JAXBContext.newInstance(classes.toArray(new Class[]{}));
         } catch (JAXBException e) {
             Logger.error(e, "Problem initializing jaxb context: %s", e.getMessage());
         }
     }
    public Object bind(String name, Class clazz, Type type, Annotation[] annotations, Map<String, String[]> params) {
         String contentType = Request.current().contentType;
 
         if (Request.current().path.startsWith("/api/") && "application/xml".equals(contentType)) {
             return getXml(clazz);
         }
 
         return null;
     }
    private Object getXml(Class    clazz) {
         try {
             if (clazz.getAnnotation(XmlRootElement.class) != null) {
                 Unmarshaller um = jc.createUnmarshaller();
 
                 XMLInputFactory factory = XMLInputFactory.newInstance();
                 XMLStreamReader sr = factory
                         .createXMLStreamReader(new StringReader(Request.current().params.get("body")));
 
                 return um.unmarshal(sr, clazz).getValue();
             }
         } catch (JAXBException e) {
             Logger.error("Problem parsing XML: [%s], class=%s", Request.current().params.get("body"), clazz);
         } catch (XMLStreamException e) {
             Logger.error("Problem parsing XML: [%s], class=%s", Request.current().params.get("body"), clazz);
         }
         return null;
     }
2. xml文档和java对象的mapping
 
@XmlRootElement(name="customer")
 @XmlAccessorType(XmlAccessType.PROPERTY)
 public class CustomerDto {
     private String customer_name;
    private String customer_kana;
//get
//set
 
}
3.到目前为止,我们可以在action里取到绑定好的java对象,根据该对象,进行业务代码的编写了。
不过我们还面临着一些共同问题,比如如果xml没有指定的话,绑定后的java对象就是null等。play充分利用了java的反射功能,我们可以很容易的解决这个问题。
 
    static void checkDtoIfNull() {
 
         Method m = (Method) ActionInvoker.getActionMethod(Http.Request.current().action)[1];
 
         try {
             Object[] paramsValues = ActionInvoker.getActionMethodArgs(m, null);
             Class<?>[] paramsTypes = m.getParameterTypes();
 
             for (int i = 0; i < paramsTypes.length; i++) {
 
                 if (paramsTypes[i].isAnnotationPresent(XmlRootElement.class) && paramsValues[i] == null) {
                     badRequest("E0001", "リクエストボティからの値取得に失敗しました", "リクエストボティには xml 形式でパラメータを指定してください");
                 }
             }
         } catch(Exception e) {
             throw new UnexpectedException("Parameter values not found for method " + m);
         }
     }
4。 在action中完成了我们的业务代码之后,渲染xml模板文件,生成xml内容,最终通过http方式返回客户端
轻量级 和 重量级web service 的思考:
 
重量级web service:
webService三要素:SOAP、WSDL (Web Services Description Language)、UDDI( Universal Description Discovery and Integration )之一, soap用来传递信息的格式, WSDL 用来描述如何访问具体的接口, uddi用来管理,分发,查询webService 具体实现可以搜索 Web Services简单实例
SOAP使用基于XML的数据结构和超文本传输协议(HTTP)的组合定义了一个标准的方法来使用Internet上各种不同操作环境中的分布式对象
轻量级web service:
http加xml,不需要wsdl和uddi,同时对soap进行了简化。
通过比较,我们认识到了轻量级web service的巨大优势,这也是为什么轻量级web service 现在这么流行的原因。