3

AndroidクライアントにRestTemplateを使用しています。私は単純な XML 注釈付きオブジェクトと、サーバー側で JaxB 注釈付きの同じ Java オブジェクトを使用しています。String やその他のプリミティブ型の送受信には成功していますが、バイト配列には問題があります。シンプル XML から送信しているバイト配列は、サーバーの JaxB 側で見ると別のものに変換されます。以下はコードです..

REST サーバー上の JaxB アノテーション付きオブジェクト

import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Device implements Serializable
{
    private final static long serialVersionUID = 1L;
    protected byte[] imageRef;

    public Device() {
        super();
    }

    public byte[] getImageRef() {
        return imageRef;
    }

    public void setImageRef(byte[] imageRef) {
        this.imageRef = imageRef;
    }
}

これがRestサーバーの外観です..私はそのためにApache CXFを使用しています。

<bean id="xmlBeanProvider" class="org.apache.cxf.jaxrs.provider.XMLBeansElementProvider"/>
    <bean id="jacksonJsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>

    <jaxrs:server id="dataRESTService" address="/">
         <jaxrs:serviceBeans>
            <ref bean="MyDataRESTService"/>
        </jaxrs:serviceBeans>
        <jaxrs:providers>
            <ref bean="xmlBeanProvider"/>
            <ref bean="jacksonJsonProvider"/>
        </jaxrs:providers>
    </jaxrs:server>
    <context:component-scan base-package="com.xxx.restservices" />

そしてコントローラー

@Path("/mydata")
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
@Service
public class MyDataRESTService 
{   
    @POST
    @Path("/testpost")
    public String testPost(Device device)
    {
        //device.getImageRef() returns [-41, 109, -8] for the bytes
    }
}

Android クライアント側の外観は次のとおりです。

Android 上の単純な XML 注釈付きオブジェクト

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root
public class Device implements Serializable
{
    private final static long serialVersionUID = 1L;
    @Element
    protected byte[] imageRef;

    public Device() {
        super();
    }

    public byte[] getImageRef() {
        return imageRef;
    }

    public void setImageRef(byte[] imageRef) {
        this.imageRef = imageRef;
    }   
}

シンプルな XML コンバーターを備えた RestTemplate クライアント

public void testPost() 
 {

          RestTemplate restTemplate = new RestTemplate();
          Serializer serializer = new Persister();
      restTemplate.getMessageConverters().add(new          SimpleXmlHttpMessageConverter(serializer));
       restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
       restTemplate.getMessageConverters().add(new FormHttpMessageConverter());

       Device device = new Device();
       device.setImageRef(new byte[]{1,2,3,4,5});
       String response =  restTemplate.postForObject("http://10.0.0.3:8080/rest/mydata/testpost", device, String.class);
        assertNotNull(response);

 }

したがって、基本的に、サーバーでbyte[]{1,2,3,4,5}のバイト配列を送信すると、このバイト配列 [-41, 109, -8]が取得されます。サーバー側でBase64でデコードしようとしましたが、単純なxmlがエンコードされている可能性があると考えていましたが、何が起こっているのかわかりませんでしたか?

同様に、Post の代わりに Get 操作を行うと、Android クライアントで NumberFormat 例外が発生します。 lang.Integer.invalidInt(Integer.java:138) で java.lang.Integer.parse(Integer.java:375) で java.lang.Integer.parseInt(Integer.java:366) で java.lang.Byte.parseByte (Byte.java:214) で java.lang.Byte.parseByte(Byte.java:195) で java.lang.Byte.valueOf(Byte.java:264) で org.simpleframework.xml.transform.ByteTransform.read( ByteTransform.java:55)

どんな助けでも大歓迎です。

4

3 に答える 3

1

やった...私はそれを働かせました。ふぅ..だから私はこのByteArrayConverterを単純なxmlで書きました。byte[] の周りに ByteArrayWrapper というラッパー クラスを作成し、Converter を Converter に置き換えます。

public class ByteArrayConverter implements Converter<ByteArrayWrapper>
{
    @Override
    public ByteArrayWrapper read(InputNode node) throws Exception 
    {
        InputNode nextnode = node.getNext();
        return new ByteArrayWrapper(Base64.decode(nextnode.getValue()));
    }

    public void write(OutputNode node, ByteArrayWrapper byteArray) throws Exception 
    {       
        OutputNode byteArrayNode = node.getChild("byteArray");
        byteArrayNode.setValue(Base64.encode(byteArray.getByteArray(), false));     
    }

}

ここに私の単純な ByteArrayWrapper クラスがあります

@Root
public class ByteArrayWrapper
{
    @Element
    protected byte[] byteArray;

    public ByteArrayWrapper()
    {
        super();
    }

    getters..
        setters..
}

Device クラスの外観は次のとおりです。

@Root
public class Device implements Serializable
{
    private final static long serialVersionUID = 1L;
    @Element
    @Convert(ByteArrayConverter.class)
    private ByteArrayWrapper imageRef;

    public Device() {
        super();
    }

    public ByteArrayWrapper getImageRef() {
        return imageRef;
    }

    public void setImageRefByteArrayWrapper imageRef) {
        this.imageRef = imageRef;
    }   
}

そして最後に RestTemplate クライアント

public void testPost() 
 {

      RestTemplate restTemplate = new RestTemplate();          
      Strategy strategy = new AnnotationStrategy();
      Serializer serializer = new Persister(strategy);
      restTemplate.getMessageConverters().add(new     SimpleXmlHttpMessageConverter(serializer));
       restTemplate.getMessageConverters().add(new StringHttpMessageConverter());


       Device device = new Device();
       device.setImageRef(new byte[]{1,2,3,4,5});
       String response =  restTemplate.postForObject("http://10.0.0.3:8080/rest/mydata/testpost", device, String.class);
        assertNotNull(response);
 }

すべてがうまくいっています!@Blaise Doughan さん、ご指摘ありがとうございます。

于 2013-07-11T14:54:28.533 に答える
0

JAXB 実装では、aが XML のbyte[]ように表現されることが期待されます。base64Binaryあなたのコメントに基づいて、単純な XML には次の表現がありますbyte[]

<imageRef length="5">1, 2, 3, 4, 5</imageRef>

base64BinaryJAXB の表現を使用するか、Simple XML の独自の表現を使用するかを選択し、反対側のアダプター/コンバーターを使用して、選択した表現を理解させる必要があります。

于 2013-07-09T16:31:56.193 に答える