自定义WebService 的 DataBinding

来源:互联网 发布:东方网络彭朋 董事长 编辑:程序博客网 时间:2024/05/01 05:03

 

CXF 中引入了一个 annotation: @DataBinding(org.apache.cxf.annotations.DataBinding), 可以用于标注一个WebService接口,指明特定的DataBinding, 从而避免使用默认的DataBinding(当然也可以通过配置文件的形式指定DataBinding,而这种annotation的方式要简便一些)。

同时,程序员可以编写自己的DataBinding类,来完全控制数据绑定的方式。

JAXB 和 AegisDataBinding都有自己的不足之处,自己编写DataBinding,在某些条件下可以弥补这些现有的DataBinding的不足。

例如,如果WebService的接口方法中,所有参数和返回值都是Serializable的,那么可以自己定义一个SerializableDatabinding,这样就不必关心参数、返回值的类型,是否有无参数的构造方法、是否是泛型等问题;同时,网络上传输的不再是明文。虽然没有加密,但也有一定程度的保密作用。

下面就是这个SerializableDatabinding的所需代码,有了这些代码就可以在特定的WebService接口上使用@DataBinding来指定这个新的DataBinding了。例如:

@WebService
@DataBinding(SerializableZipDatabinding.class)
public interface IDBUtilSvc {
    public CachedRowSet getRowSetBySql(String asConnKey, StringasSelectSql,int aiPageSize,int aiPageIndex)
    throws SQLException;


}

  • SerializableDatabinding.java

package cn.yanggq.webservice.databinding.serializer; 

import  javax.xml.stream.XMLStreamReader;

import  javax.xml.stream.XMLStreamWriter;

import  org.apache.cxf.databinding.DataReader;

import  org.apache.cxf.databinding.DataWriter;

import  org.apache.cxf.service.Service;

import  org.apache.log4j.Logger;

import  org.w3c.dom.Node;

/**

这个类提供一种简单的WebService的数据邦定方式,凡是Serializable的对象都可以作为参数或者返回值转递。

*  <BR>计划还要支持数据压缩。

*  <br><B></B>:目前可能还不成熟。

*  @author stoney(YangGQ)

*

*/

//public  class AnyDatabinding implements DataBinding {

public  class SerializableDatabinding extends org.apache.cxf.databinding.AbstractDataBinding{

     static Logger logger = Logger.getLogger(SerializableDatabinding.class);

     protected Class<?>  supportedReaderFormat[]={SerializableDataReader.class,  Node.class,XMLStreamReader.class};

     protected Class<?> supportedWriterFormat[]={SerializableDataWriter.class,  Node.class,XMLStreamWriter.class};

     @Override

     public <T> DataReader<T> createReader(Class<T> cls) {

         logger.trace("Getting DataReader of " +cls);

         return new SerializableDataReader<T>();

     }

     @Override

     public <T> DataWriter<T> createWriter(Class<T> cls) {

         logger.trace("Getting DataWriter of " +cls);

         return new SerializableDataWriter<T>();

     }

     @Override

     public Class<?>[] getSupportedReaderFormats() {

         return supportedReaderFormat;

     }

     @Override

     public Class<?>[] getSupportedWriterFormats() {

         return supportedWriterFormat;

     }

     @Override

     public void initialize(Service service) {

         //Do Nothing?

     }

}

 

  • SerializableDataReader.java

package cn.yanggq.webservice.databinding.serializer; 

import java.util.Collection;

import javax.xml.namespace.QName;
  import javax.xml.stream.XMLStreamReader;
  import javax.xml.validation.Schema;

import org.apache.cxf.databinding.DataReader;
  import org.apache.cxf.message.Attachment;
  import org.apache.cxf.service.model.MessagePartInfo;
  import org.apache.log4j.Logger;

import  com.ordinov.application.exception.OAFRuntimeException;
  import com.ordinov.util.DataProcessor;
  import com.ordinov.util.Serializer;

/**
  * Serializable数据的Reader。

  * @author stoney(YangGQ)
  *
  * @param <T>
  */
  public class SerializableDataReader<T> implements DataReader<T>{
      private static Logger logger =  Logger.getLogger(SerializableDataReader.class);
      private boolean dataCompressed = false;
      public SerializableDataReader()
      {
      }
      public SerializableDataReader(boolean abDataCompressed)
      {
          dataCompressed = abDataCompressed;
      }
      @Override
      public Object read(Object input) {
          logger.trace("reading "+  input);
          if (input instanceof  XMLStreamReader ){
              return  read(null,(XMLStreamReader)input);
          }else{
              throw new  OAFRuntimeException("
不支持的input:"+input);
          }
      }

    @Override
      public Object read(MessagePartInfo part, Object input) {
  //        logger.trace("reading  "+ input +"\n\tMessagePart:"+part);
          if (input instanceof  XMLStreamReader ){
              return  read(part,(XMLStreamReader)input);
          }else{
              throw new  OAFRuntimeException("不支持的
input:"+input);
          }
      }
      public Object read(MessagePartInfo part, XMLStreamReader  reader) {
          Object loRet = null;
          try {
              String  lsEleName = reader.getLocalName();
               logger.trace("\tReading data of (LocalName) "+lsEleName);
              String  lsData = reader.getElementText();
  //             logger.trace("\tElement Text="+lsData);
              byte  sBytes[] = (new sun.misc.BASE64Decoder()).decodeBuffer( lsData );
              if  (dataCompressed){
  //                 logger.trace("\tData compressed, deCompressing...");
                   sBytes = DataProcessor.DeCompressData(sBytes);
              }
              Serializer  s = new Serializer();
              loRet =  s.deSerializeAny(sBytes);
               logger.trace("\t\tElement '"+ lsEleName +"' Class:"+  (loRet!=null?loRet.getClass():null)+", Value="+loRet);
               if(reader.hasNext())
                   reader.next();//非常关键!不调用此方法只能读取一个参数arg0(不知何故?本来理解应该是外部控制多次调用的
)
          } catch (Exception e) {
              throw new  OAFRuntimeException("无法读取数据并转换为对象
",e);
          }
          return loRet;
      }

    @Override
      public Object read(QName elementQName, Object input, Class  type) {
          logger.trace("reading "+  input +"\t\nQName:"+elementQName
                   +"\n\tAs Type:"+type);
          if (input instanceof  XMLStreamReader ){
              return  read(null,(XMLStreamReader)input);
          }else{
              throw new  OAFRuntimeException("不支持的
input:"+input);
          }
      }

    @Override
      public void setAttachments(Collection<Attachment>  attachments) {
          logger.trace("setAttachments:  "+attachments);        
      }

    @Override
      public void setProperty(String prop, Object value) {
          logger.trace("setProperty:  "+prop + "->" + value);    
      }

    @Override
      public void setSchema(Schema s) {
          logger.trace("setSchema:  "+s);    
      }

    public boolean isDataCompressed() {
          return dataCompressed;
      }
      public void setDataCompressed(boolean dataCompressed) {
          this.dataCompressed =  dataCompressed;
      }

}

 

  • SerializableDataWriter.java

package cn.yanggq.webservice.databinding.serializer; 

import java.util.Collection;

import javax.xml.stream.XMLStreamWriter;
  import javax.xml.validation.Schema;

import org.apache.cxf.aegis.xml.stax.ElementWriter;
  import org.apache.cxf.databinding.DataWriter;
  import org.apache.cxf.message.Attachment;
  import org.apache.cxf.service.model.MessagePartInfo;
  import org.apache.log4j.Logger;

import  com.ordinov.application.exception.OAFRuntimeException;
  import com.ordinov.util.DataProcessor;
  import com.ordinov.util.Serializer;

/**
  * Serializable数据的Writer。

  *
  * @author stoney(YangGQ)
  *
  * @param <T>
  */

public class SerializableDataWriter<T> implements  DataWriter<T>{
      private static Logger logger = Logger.getLogger(SerializableDataWriter.class);
      private boolean dataCompressed = false;
      public SerializableDataWriter()
      {}
      public SerializableDataWriter(boolean abDataCompressed)
      {
          dataCompressed = abDataCompressed;
      }
      @Override
      public void write(Object obj, Object output) {
          logger.trace("writing  '"+ obj + "' to "+output);
      }

    @Override
      public void write(Object obj, MessagePartInfo part, Object  output) {
  //        logger.trace("writing  '"+ obj + "' to "+output +
  //                 "\n\tMessagePartIngo:"+part);
          if (output instanceof  XMLStreamWriter){
               this.write(obj, part, (XMLStreamWriter)output);
          }else{
              throw new  OAFRuntimeException("不支持的
output:"+output);
          }
      }
      public void write(Object obj, MessagePartInfo part,  XMLStreamWriter output)
      {
          try {
               logger.trace("writing data '"+ obj + "', LocalName:  "+part.getElementQName());
              Serializer  s = new Serializer();
              byte  sBytes[] = s.serializeAny(obj);
              if  (dataCompressed){
  //                 logger.trace("\tData should be compressed, compressing...");
                   sBytes = DataProcessor.CompressData(sBytes);
              }
              String  lsData = (new sun.misc.BASE64Encoder()).encode( sBytes );
  //             output.writeAttribute("ENCODED_DATA", lsData);
               ElementWriter writer = new ElementWriter(output,part.getElementQName());
               writer.writeValue(lsData);
               writer.close();//必须!

        }catch  (Exception e){
              throw new  OAFRuntimeException("写对象时出错!
",e);
          }
      }

    @Override
      public void setAttachments(Collection<Attachment>  attachments) {
          logger.trace("setAttachments:  "+attachments);
      }

    @Override
      public void setProperty(String key, Object value) {
          logger.trace("setProperty:  "+key + "->" + value);    
      }

    @Override
      public void setSchema(Schema s) {
          logger.trace("setSchema:  "+s);    
      }
      public boolean isDataCompressed() {
          return dataCompressed;
      }
      public void setDataCompressed(boolean dataCompressed) {
          this.dataCompressed =  dataCompressed;
      }

}

 

原创粉丝点击