2015-01-05 3 views
0

키가 문자열이고 값이 인터페이스 인 맵이 있습니다. 필자는 인터페이스를 처리 할 어댑터를 작성하고지도 필드에 @XmlAnyElement 주석을 제공했습니다. 이제 @ "XmlRootElement annotation이 없기 때문에 java.util.HashMap"요소를 마샬링 할 수 없다는 오류가 나타납니다. 이 문제에 대해 아무도 도와 줄 수 없습니까?JAXB "java.util.HashMap"형식을 마샬링 할 수 없습니다.

답변

0

이 오류는 Map이 XmlRootElement가 아니기 때문에 발생합니다. 이 인터페이스입니다

:의를 예로 들어 보자

public interface IEmployee { 

    String getFirstName(); 

    void setFirstName(final String firstName); 

    String getLastName(); 

    void setLastName(final String lastName); 

} 

을 그리고이 콘크리트 구현 :

@XmlRootElement(name = "employee") 
public class Employee implements IEmployee { 

    private String firstName; 
    private String lastName; 

    // getters and setters 

} 
지도

JAXB 객체 :

import java.util.Map; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlRootElement(name = "employees") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class EmployeeMap { 

    @XmlJavaTypeAdapter(EmployeeMapAdapter.class) 
    private Map<String, IEmployee> map; 

    // getter and setter 

} 

우리는 만들 필요 EmployeeMap의지도를 처리하는 어댑터가지도를 시뮬레이트하는 목록으로 표시됩니다. 이 모양은 다음과 같습니다.

public class EmployeeMapAdapter extends XmlAdapter<EmployeeMapAdapter.AdaptedMap, Map<String, Employee>> { 

    public static class AdaptedMap { 

     public List<Entry> entry = new ArrayList<>(); 

     public static class Entry { 

      public String key; 
      public Employee value; 

     } 

    } 

    @Override 
    public AdaptedMap marshal(final Map<String, Employee> map) throws Exception { 
     final AdaptedMap adaptedMap = new AdaptedMap(); 
     for (final Map.Entry<String, Employee> mapEntry : map.entrySet()) { 
      final Entry entry = new Entry(); 
      entry.key = mapEntry.getKey(); 
      entry.value = mapEntry.getValue(); 
      adaptedMap.entry.add(entry); 
     } 
     return adaptedMap; 
    } 

    @Override 
    public Map<String, Employee> unmarshal(final AdaptedMap adaptedMap) throws Exception { 
     final Map<String, Employee> map = new HashMap<>(); 
     for (final Entry entry : adaptedMap.entry) { 
      map.put(entry.key, entry.value); 
     } 
     return map; 
    } 

} 

JAXB는 값 클래스와 콘텐츠 인터페이스 만 처리하기 때문에 어댑터는 구체적인 구현을 사용해야합니다.

마샬링 예 :

final Map<String, IEmployee> map = new HashMap<>(); 

final Employee emp1 = new Employee(); 
emp1.setFirstName("Bruno"); 
emp1.setLastName("César"); 
map.put("1", emp1); 

final Employee emp2 = new Employee(); 
emp2.setFirstName("Ribeiro"); 
emp2.setLastName("Silva"); 
map.put("2", emp2); 

final EmployeeMap employeeMap = new EmployeeMap(); 
employeeMap.setMap(map); 

final JAXBContext jaxbContext = JAXBContext.newInstance(EmployeeMap.class); 
final Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

final File file = new File("D:/Temp/employees.xml"); 
if (!file.exists()) { 
    file.mkdirs(); 
} 

jaxbMarshaller.marshal(employeeMap, file); 

의 결과 :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<employees> 
    <map> 
     <entry> 
      <key>2</key> 
      <value> 
       <firstName>Ribeiro</firstName> 
       <lastName>Silva</lastName> 
      </value> 
     </entry> 
     <entry> 
      <key>1</key> 
      <value> 
       <firstName>Bruno</firstName> 
       <lastName>César</lastName> 
      </value> 
     </entry> 
    </map> 
</employees> 

그리고 비 정렬 화 :

final JAXBContext jaxbContext = JAXBContext.newInstance(EmployeeMap.class); 
final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
final EmployeeMap empMap = (EmployeeMap) jaxbUnmarshaller.unmarshal(new File("D:/temp/employees.xml")); 

for (final String id : empMap.getMap().keySet()) { 
    System.out.println(empMap.getMap().get(id).getFirstName()); 
    System.out.println(empMap.getMap().get(id).getLastName()); 
} 

결과 :

Ribeiro 
Silva 
Bruno 
César 
관련 문제