1. 目的
开发rest 请求创建service, 利用post 请求,并且携带message body,JSON格式,包括service的配置信息,从而实现service添加
2. 关键要点
利用 post请求传输json数据并返还json格式结果
3. 关键代码
@POST @Path("/service/deploy") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public String createService(NgmaServiceConfig serviceconfig) { log.info("create service"); log.info("the service config received is {}",serviceconfig); /** { "serviceName":"provision", "serviceNode":{"nodeName":"node1"}, "serviceAttributes":{"pname":"aaa"} } */ JsonObject json = new JsonObject(); //generate service id randomly UUID serviceID=UUID.randomUUID(); //append other attributes for service in demo serviceconfig.setServiceId(serviceID); NgmaServiceNode node = new NgmaServiceNode(); node.setNodeId(UUID.fromString("24c0a3f7-5d34-48bc-8472-90f98836033b")); node.setNodeName("node1"); serviceconfig.setServiceName("provision"); serviceconfig.setServiceNode(node); NgmaServiceType serviceType = new NgmaServiceType(); serviceType.setServiceTypeId(UUID.fromString("8ef879ef-3837-4d24-b53e-79c191624c52")); serviceconfig.setServiceType(serviceType); try { servicedata.saveServiceConfig(serviceconfig); } catch (PlcmStatusException e) { // TODO implement catch PlcmStatusException log.debug("failed to create service ", e); } json.addProperty("serviceUUID",serviceID.toString()); return json.toString(); }重点分析:
@Consumes(MediaType.APPLICATION_JSON)指明接受的数据类型是json格式
@Produces(MediaType.APPLICATION_JSON)
指定返回的数据类型是json格式
NgmaServiceConfigpost请求的json格式service信息会转为NgmaServiceConfig,主要是配置jackson,CXF与Jackson结合,jason把json序列化,反序列化映射到POJO类的属性上。详细资料可以研究jackson,其他开源实现jettison也可以实现。
此处POJO的属性必须与json的配置属性一致,包括大小写,如下所示:
{ "serviceName":"provision", "serviceNode":{"nodeName":"node1"}, "serviceAttributes":{"pname":"aaa"} }
@XmlRootElement(name = "serviceconfig") public class NgmaServiceConfig extends MemEntity implements Serializable { /** * */ private static final long serialVersionUID = -6005926332718108639L; private UUID serviceId; private String serviceName; // private UUID nodeId; @NgmaRefObjectAnnotation(type = "object", getter = "getServiceNode", setter = "setServiceNode") private NgmaServiceNode serviceNode; // private UUID serviceTypeId; @NgmaRefObjectAnnotation(type = "object", getter = "getServiceType", setter = "setServiceType") private NgmaServiceType serviceType; @NgmaRefObjectAnnotation(type = "list", getter = "getServiceDefinedTransport", setter = "setServiceDefinedTransport") private List<NgmaTransport> serviceDefinedTransport; private Map<String, String> serviceAttributes;
{
serviceconfig:{ "serviceName":"provision", "serviceNode":{"nodeName":"node1"}, "serviceAttributes":{"pname":"aaa"} }
}因为pojo类中配置了xmlroot,所以我想json也是,我demo的例子也的确是这样,但是不太清楚为什么现在的工程不能识别?害的我搞了很久。
@XmlRootElement(name = "serviceconfig")
4. 问题
1.
org.apache.cxf.jaxrs.client.ClientWebApplicationException:No message body writer found forclass
配置引入jackson-jxr.jar并在spring配置文件中配置,如下:
<jaxrs:server id="ngmaServiceStatus" address="/ngma"> <jaxrs:serviceBeans> <ref bean="ngmaServiceStatusBean" /> </jaxrs:serviceBeans> <strong> <span style="color:#ff6666;"><jaxrs:providers> <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/> </jaxrs:providers></span></strong> </jaxrs:server>
3. jackson支持hashmap list等集合的属性映射。
private Map<String, List<MyHolder>> propertyName;
class MyHolder { @JsonProperty("1") private String name; @JsonProperty("2") private String age; @JsonProperty("3") private boolean female; //getters,setters,toString }
对于的json格式如下:
{ "propertyName":{ "1":[ { "1":"value1", "2":"value2", "3":false } ] } }
5. 参考link
http://www.javatips.net/blog/2012/02/cxf-restful-tutorial
http://blog.csdn.net/unei66/article/details/12324353
http://wiki.fasterxml.com/JacksonDownload
http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-Formpayloads
http://stackoverflow.com/questions/6312030/cxf-no-message-body-writer-found-for-class-automatically-mapping-non-simple-r