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 现在这么流行的原因。