Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HashMap的XMLAdapter_Java_Jaxb_Jersey_Jax Rs - Fatal编程技术网

Java HashMap的XMLAdapter

Java HashMap的XMLAdapter,java,jaxb,jersey,jax-rs,Java,Jaxb,Jersey,Jax Rs,我想将payaload中的项目列表转换为hashmap。基本上,我有一个itemXML表示,它有一个ItemID列表。每个ItemID中都有一个idType。但是,在我的Item类中,我希望这些ItemIDs被表示为一个映射 HashMap<ItemIDType, ItemID> 我现在正在使用LinkedList public class MapHashMapListAdapter extends XmlAdapter<LinkedList<ItemID>, M

我想将payaload中的项目列表转换为hashmap。基本上,我有一个itemXML表示,它有一个ItemID列表。每个ItemID中都有一个idType。但是,在我的Item类中,我希望这些ItemIDs被表示为一个映射

HashMap<ItemIDType, ItemID>
我现在正在使用LinkedList

public class MapHashMapListAdapter extends XmlAdapter<LinkedList<ItemID>, Map<ItemIDType, ItemID>> {

     public LinkedList<ItemID> marshal(final Map<ItemIDType, ItemID> v) throws Exception { ... }

     public Map<ItemIDType, ItemID> unmarshal(final LinkedList<ItemID> v) throws Exception { ... }

}
公共类MapHashMapListAdapter扩展了XmlAdapter{
公共LinkedList封送处理程序(最终映射v)引发异常{…}
公共映射解组(最终LinkedList v)引发异常{…}
}

但由于某种原因,当我的有效负载被转换时,它无法将列表转换为hashmap。方法unmarshal的传入LinkedList是空列表。你们知道我做错了什么吗?我是否需要在此处创建自己的数据类型来处理LinkedList?

您需要将
映射转换为
LinkedList
,而不是将其转换为域对象

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public final class MyMapAdapter extends

   XmlAdapter<MyMapType,Map<Integer, String>> {

   @Override
   public MyMapType marshal(Map<Integer, String> arg0) throws Exception {
      MyMapType myMapType = new MyMapType();
      for(Entry<Integer, String> entry : arg0.entrySet()) {
         MyMapEntryType myMapEntryType =
            new MyMapEntryType();
         myMapEntryType.key = entry.getKey();
         myMapEntryType.value = entry.getValue();
         myMapType.entry.add(myMapEntryType);
      }
      return myMapType;
   }

   @Override
   public Map<Integer, String> unmarshal(MyMapType arg0) throws Exception {
      HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
      for(MyMapEntryType myEntryType : arg0.entry) {
         hashMap.put(myEntryType.key, myEntryType.value);
      }
      return hashMap;
   }

}
import java.util.HashMap;
导入java.util.Map;
导入java.util.Map.Entry;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
公共最终类MyMapAdapter扩展
XmlAdapter{
@凌驾
公共MyMapType封送处理程序(映射arg0)引发异常{
MyMapType MyMapType=新的MyMapType();
对于(条目:arg0.entrySet()){
MyMapEntryType MyMapEntryType=
新建MyMapEntryType();
myMapEntryType.key=entry.getKey();
myMapEntryType.value=entry.getValue();
myMapType.entry.add(myMapEntryType);
}
返回myMapType;
}
@凌驾
公共映射解组器(MyMapType arg0)引发异常{
HashMap HashMap=新的HashMap();
对于(MyMapEntryType myEntryType:arg0.entry){
put(myEntryType.key,myEntryType.value);
}
返回hashMap;
}
}
了解更多信息


您可以参考此处的oracle官方文档:
. 他们为HashMap给出了一个类似的例子。

您可以使用我以前的通用解决方案,但在实际项目中永远不要这样做,,它不是跨语言的(它仅适用于java客户端+java服务器解决方案)。java可以封送和解封任何java对象。为了进行封送处理,它将java对象序列化为字符串,然后将其编码为base64。对于解组,它解码base64字符串并反序列化它以获取java对象。顺便说一句,在这个解决方案中,服务器端和客户端都需要助手(SerializableAdapler.java、Base64Coder.java)。在正常的解决方案中,客户端只需要一个接口,如SomeService.java(服务器端同时需要SomeService.java和SomeServiceImpl.java)。我用进行了测试,但您可以使用其他webservices框架

SomeService.java

package some.services.interfaces;

import some.services.interfaces.helpers.SerializableAdapler;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.List;
import java.util.Map;

@WebService
public interface SomeService {
    String sayHi(@WebParam(name = "text") String text);

    String sayHiToUser(@WebParam(name = "user") String user);

    /* Advanced usecase of passing an Interface in.  JAX-WS/JAXB does not
     * support interfaces directly.  Special XmlAdapter classes need to
     * be written to handle them
     */
    boolean add(@XmlJavaTypeAdapter(SerializableAdapler.class) @WebParam(name = "data") Map<String, String> data);

    boolean addAll(@XmlJavaTypeAdapter(SerializableAdapler.class) @WebParam(name = "columns") List<String> columns, @XmlJavaTypeAdapter(SerializableAdapler.class) @WebParam(name = "datas") List<List<String>> datas);

    @XmlJavaTypeAdapter(SerializableAdapler.class)
    List<String> showColumns();

    @XmlJavaTypeAdapter(SerializableAdapler.class)
    List<List<String>> getDatas();
}
SomeServiceImpl.java

package some.services.implement;

import some.services.interfaces.SomeService;

import javax.jws.WebService;
import java.util.*;

@WebService(endpointInterface = "some.services.interfaces.SomeService",
        serviceName = "SomeService")
public class SomeServiceImpl implements SomeSerive {
    public String sayHi(String text) {
        return "Hi, "+text;
    }

    public String sayHiToUser(String user) {
        return "Hello, "+user;
    }

    protected List<String> columns = null;
    protected final List<List<String>> datas = new LinkedList<List<String>>();

    public boolean add(Map<String, String> data) {
        ...
    }

    public boolean addAll(List<String> columns, List<List<String>> datas) {
        ...
    }

    public List<String> showColumns() {
        ...
    }

    public List<List<String>> getDatas() {
        ...
    }
}
打包some.services.implement;
导入some.services.interfaces.SomeService;
导入javax.jws.WebService;
导入java.util.*;
@WebService(endpointInterface=“some.services.interfaces.SomeService”,
serviceName=“SomeService”)
公共类SomeServiceImpl实现了SomeSerive{
公共字符串sayHi(字符串文本){
返回“Hi,”+文本;
}
公共字符串sayHiToUser(字符串用户){
返回“你好,”+用户;
}
受保护列表列=null;
受保护的最终列表数据=新建LinkedList();
公共布尔添加(地图数据){
...
}
公共布尔addAll(列表列、列表数据){
...
}
公共列表显示列(){
...
}
公共列表getDatas(){
...
}
}

注:此解决方案示例适用于Java 7(不支持正常的base64)。请不要为以后的Java版本进行编辑。

什么是无法转换?您是否收到了一些错误消息,或者发生了一些您意想不到的事情?很可能错误在您没有显示的代码中。我最终也创建了自己的数据类型。
package some.services.interfaces;

import some.services.interfaces.helpers.SerializableAdapler;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.List;
import java.util.Map;

@WebService
public interface SomeService {
    String sayHi(@WebParam(name = "text") String text);

    String sayHiToUser(@WebParam(name = "user") String user);

    /* Advanced usecase of passing an Interface in.  JAX-WS/JAXB does not
     * support interfaces directly.  Special XmlAdapter classes need to
     * be written to handle them
     */
    boolean add(@XmlJavaTypeAdapter(SerializableAdapler.class) @WebParam(name = "data") Map<String, String> data);

    boolean addAll(@XmlJavaTypeAdapter(SerializableAdapler.class) @WebParam(name = "columns") List<String> columns, @XmlJavaTypeAdapter(SerializableAdapler.class) @WebParam(name = "datas") List<List<String>> datas);

    @XmlJavaTypeAdapter(SerializableAdapler.class)
    List<String> showColumns();

    @XmlJavaTypeAdapter(SerializableAdapler.class)
    List<List<String>> getDatas();
}
package some.services.interfaces.helpers;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.io.*;

public class SerializableAdapler<BoundType> extends XmlAdapter<String,BoundType> {
    @Override
    public BoundType unmarshal(String v) throws Exception {
        byte [] data = Base64Coder.decode( v );
        ObjectInputStream ois = new ObjectInputStream(
                new ByteArrayInputStream(  data ) );

        BoundType o  = (BoundType)ois.readObject();
        ois.close();
        return o;
    }

    @Override
    public String marshal(BoundType v) throws Exception {
        if (v instanceof Serializable) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(v);
            oos.close();
            return new String(Base64Coder.encode(baos.toByteArray()));
        } else {
            throw new Exception("BoundType v is not serializable: "+v.getClass());
        }
    }
}
package some.services.interfaces.helpers;

// Copyright 2003-2010 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
// www.source-code.biz, www.inventec.ch/chdh
//
// This module is multi-licensed and may be used under the terms
// of any of the following licenses:
//
//  EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal
//  LGPL, GNU Lesser General Public License, V2.1 or later, http://www.gnu.org/licenses/lgpl.html
//  GPL, GNU General Public License, V2 or later, http://www.gnu.org/licenses/gpl.html
//  AGPL, GNU Affero General Public License V3 or later, http://www.gnu.org/licenses/agpl.html
//  AL, Apache License, V2.0 or later, http://www.apache.org/licenses
//  BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php
//  MIT, MIT License, http://www.opensource.org/licenses/MIT
//
// Please contact the author if you need another license.
// This module is provided "as is", without warranties of any kind.
//
// Project home page: www.source-code.biz/base64coder/java

/**
 * A Base64 encoder/decoder.
 *
 * <p>
 * This class is used to encode and decode data in Base64 format as described in RFC 1521.
 *
 * @author
 *    Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland, www.source-code.biz
 */
public class Base64Coder {

    // The line separator string of the operating system.
    private static final String systemLineSeparator = System.getProperty("line.separator");

    // Mapping table from 6-bit nibbles to Base64 characters.
    private static final char[] map1 = new char[64];
    static {
        int i=0;
        for (char c='A'; c<='Z'; c++) map1[i++] = c;
        for (char c='a'; c<='z'; c++) map1[i++] = c;
        for (char c='0'; c<='9'; c++) map1[i++] = c;
        map1[i++] = '+'; map1[i++] = '/'; }

    // Mapping table from Base64 characters to 6-bit nibbles.
    private static final byte[] map2 = new byte[128];
    static {
        for (int i=0; i<map2.length; i++) map2[i] = -1;
        for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }

    /**
     * Encodes a string into Base64 format.
     * No blanks or line breaks are inserted.
     * @param s  A String to be encoded.
     * @return   A String containing the Base64 encoded data.
     */
    public static String encodeString (String s) {
        return new String(encode(s.getBytes())); }

    /**
     * Encodes a byte array into Base 64 format and breaks the output into lines of 76 characters.
     * This method is compatible with <code>sun.misc.BASE64Encoder.encodeBuffer(byte[])</code>.
     * @param in  An array containing the data bytes to be encoded.
     * @return    A String containing the Base64 encoded data, broken into lines.
     */
    public static String encodeLines (byte[] in) {
        return encodeLines(in, 0, in.length, 76, systemLineSeparator); }

    /**
     * Encodes a byte array into Base 64 format and breaks the output into lines.
     * @param in            An array containing the data bytes to be encoded.
     * @param iOff          Offset of the first byte in <code>in</code> to be processed.
     * @param iLen          Number of bytes to be processed in <code>in</code>, starting at <code>iOff</code>.
     * @param lineLen       Line length for the output data. Should be a multiple of 4.
     * @param lineSeparator The line separator to be used to separate the output lines.
     * @return              A String containing the Base64 encoded data, broken into lines.
     */
    public static String encodeLines (byte[] in, int iOff, int iLen, int lineLen, String lineSeparator) {
        int blockLen = (lineLen*3) / 4;
        if (blockLen <= 0) throw new IllegalArgumentException();
        int lines = (iLen+blockLen-1) / blockLen;
        int bufLen = ((iLen+2)/3)*4 + lines*lineSeparator.length();
        StringBuilder buf = new StringBuilder(bufLen);
        int ip = 0;
        while (ip < iLen) {
            int l = Math.min(iLen-ip, blockLen);
            buf.append(encode(in, iOff+ip, l));
            buf.append(lineSeparator);
            ip += l; }
        return buf.toString(); }

    /**
     * Encodes a byte array into Base64 format.
     * No blanks or line breaks are inserted in the output.
     * @param in  An array containing the data bytes to be encoded.
     * @return    A character array containing the Base64 encoded data.
     */
    public static char[] encode (byte[] in) {
        return encode(in, 0, in.length); }

    /**
     * Encodes a byte array into Base64 format.
     * No blanks or line breaks are inserted in the output.
     * @param in    An array containing the data bytes to be encoded.
     * @param iLen  Number of bytes to process in <code>in</code>.
     * @return      A character array containing the Base64 encoded data.
     */
    public static char[] encode (byte[] in, int iLen) {
        return encode(in, 0, iLen); }

    /**
     * Encodes a byte array into Base64 format.
     * No blanks or line breaks are inserted in the output.
     * @param in    An array containing the data bytes to be encoded.
     * @param iOff  Offset of the first byte in <code>in</code> to be processed.
     * @param iLen  Number of bytes to process in <code>in</code>, starting at <code>iOff</code>.
     * @return      A character array containing the Base64 encoded data.
     */
    public static char[] encode (byte[] in, int iOff, int iLen) {
        int oDataLen = (iLen*4+2)/3;       // output length without padding
        int oLen = ((iLen+2)/3)*4;         // output length including padding
        char[] out = new char[oLen];
        int ip = iOff;
        int iEnd = iOff + iLen;
        int op = 0;
        while (ip < iEnd) {
            int i0 = in[ip++] & 0xff;
            int i1 = ip < iEnd ? in[ip++] & 0xff : 0;
            int i2 = ip < iEnd ? in[ip++] & 0xff : 0;
            int o0 = i0 >>> 2;
            int o1 = ((i0 &   3) << 4) | (i1 >>> 4);
            int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
            int o3 = i2 & 0x3F;
            out[op++] = map1[o0];
            out[op++] = map1[o1];
            out[op] = op < oDataLen ? map1[o2] : '='; op++;
            out[op] = op < oDataLen ? map1[o3] : '='; op++; }
        return out; }

    /**
     * Decodes a string from Base64 format.
     * No blanks or line breaks are allowed within the Base64 encoded input data.
     * @param s  A Base64 String to be decoded.
     * @return   A String containing the decoded data.
     * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
     */
    public static String decodeString (String s) {
        return new String(decode(s)); }

    /**
     * Decodes a byte array from Base64 format and ignores line separators, tabs and blanks.
     * CR, LF, Tab and Space characters are ignored in the input data.
     * This method is compatible with <code>sun.misc.BASE64Decoder.decodeBuffer(String)</code>.
     * @param s  A Base64 String to be decoded.
     * @return   An array containing the decoded data bytes.
     * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
     */
    public static byte[] decodeLines (String s) {
        char[] buf = new char[s.length()];
        int p = 0;
        for (int ip = 0; ip < s.length(); ip++) {
            char c = s.charAt(ip);
            if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
                buf[p++] = c; }
        return decode(buf, 0, p); }

    /**
     * Decodes a byte array from Base64 format.
     * No blanks or line breaks are allowed within the Base64 encoded input data.
     * @param s  A Base64 String to be decoded.
     * @return   An array containing the decoded data bytes.
     * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
     */
    public static byte[] decode (String s) {
        return decode(s.toCharArray()); }

    /**
     * Decodes a byte array from Base64 format.
     * No blanks or line breaks are allowed within the Base64 encoded input data.
     * @param in  A character array containing the Base64 encoded data.
     * @return    An array containing the decoded data bytes.
     * @throws    IllegalArgumentException If the input is not valid Base64 encoded data.
     */
    public static byte[] decode (char[] in) {
        return decode(in, 0, in.length); }

    /**
     * Decodes a byte array from Base64 format.
     * No blanks or line breaks are allowed within the Base64 encoded input data.
     * @param in    A character array containing the Base64 encoded data.
     * @param iOff  Offset of the first character in <code>in</code> to be processed.
     * @param iLen  Number of characters to process in <code>in</code>, starting at <code>iOff</code>.
     * @return      An array containing the decoded data bytes.
     * @throws      IllegalArgumentException If the input is not valid Base64 encoded data.
     */
    public static byte[] decode (char[] in, int iOff, int iLen) {
        if (iLen%4 != 0) throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4.");
        while (iLen > 0 && in[iOff+iLen-1] == '=') iLen--;
        int oLen = (iLen*3) / 4;
        byte[] out = new byte[oLen];
        int ip = iOff;
        int iEnd = iOff + iLen;
        int op = 0;
        while (ip < iEnd) {
            int i0 = in[ip++];
            int i1 = in[ip++];
            int i2 = ip < iEnd ? in[ip++] : 'A';
            int i3 = ip < iEnd ? in[ip++] : 'A';
            if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
                throw new IllegalArgumentException("Illegal character in Base64 encoded data.");
            int b0 = map2[i0];
            int b1 = map2[i1];
            int b2 = map2[i2];
            int b3 = map2[i3];
            if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
                throw new IllegalArgumentException("Illegal character in Base64 encoded data.");
            int o0 = ( b0       <<2) | (b1>>>4);
            int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
            int o2 = ((b2 &   3)<<6) |  b3;
            out[op++] = (byte)o0;
            if (op<oLen) out[op++] = (byte)o1;
            if (op<oLen) out[op++] = (byte)o2; }
        return out; }

    // Dummy constructor.
    private Base64Coder() {}

} // end class Base64Coder
package some.services.implement;

import some.services.interfaces.SomeService;

import javax.jws.WebService;
import java.util.*;

@WebService(endpointInterface = "some.services.interfaces.SomeService",
        serviceName = "SomeService")
public class SomeServiceImpl implements SomeSerive {
    public String sayHi(String text) {
        return "Hi, "+text;
    }

    public String sayHiToUser(String user) {
        return "Hello, "+user;
    }

    protected List<String> columns = null;
    protected final List<List<String>> datas = new LinkedList<List<String>>();

    public boolean add(Map<String, String> data) {
        ...
    }

    public boolean addAll(List<String> columns, List<List<String>> datas) {
        ...
    }

    public List<String> showColumns() {
        ...
    }

    public List<List<String>> getDatas() {
        ...
    }
}