3
votes

I am facing an issue in my code.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
@NamedQueries({
    @NamedQuery(name = Parameter.FIND_ALL, query = "SELECT pm FROM Parameter pm")
})
public class Parameter implements Serializable {

    public static final String FIND_ALL = "Parameter.findAll";

    @XmlTransient
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    private Long id;
    @XmlAttribute
    private String type;

    private String name;

    // Setters and Getters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ParameterMap {
    private Map<String, List<Parameter>> parameterMap = new HashMap<String, List<Parameter>>();

    @XmlElement
    public Map<String, List<Parameter>> getParameterMap() {
        return parameterMap;
    }

    public void setParmeterMap(Map<String, List<Parameter>> parameterMap) {
        this.parameterMap = parameterMap;
    }
}

@Path("/parameter")
public class ParameterRESTResource {

    @Inject
    private ParameterService paramService;

    @GET
    @Path("/")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public List<Parameter> getAllParameters() throws JAXBException {

        ParameterMap parameterMap = formatParameters(paramService.getAllParameters());

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

        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        jaxbMarshaller.marshal(parameterMap, System.out);
        jaxbMarshaller.marshal(parameterMap, new File("c:/temp/employees.xml"));

        return paramService.getAllParameters();
    }

    public ParameterMap formatParameters(List<Parameter> parameters) {
        HashMap<String, List<Parameter>> parameterMap = new HashMap<String, List<Parameter>>();
        ParameterMap paramMap = new ParameterMap();
        Parameter param = null;

        List<Parameter> list = null;

        for (int i = 0; i < parameters.size(); i++) {
            param = new Parameter();

            param = parameters.get(i);

            if (param.getType() != "text") {
                list = new ArrayList<Parameter>();

                if (parameterMap.containsKey(param.getName())) {
                    list = parameterMap.get(param.getName());
                    list.add(param);
                }
                else {
                    list = new ArrayList<Parameter>();
                    list.add(param);
                }

            }
            else {
                list = new ArrayList<Parameter>();
                list.add(param);

            }

            parameterMap.put(param.getName(), list);

        }

        paramMap.setParmeterMap(parameterMap);
        return paramMap;
    }
}

When I am running the application on my local(http://localhost:8080/home/rest/parameter/) I am getting the below error. My main requirement is to show the Map<String,List<Parameters>> on the UI with the xml with all the information.

org.jboss.resteasy.spi.UnhandledException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions java.util.List is an interface, and JAXB can't handle interfaces. this problem is related to the following location: at java.util.List at private java.util.Map nl.paston.insurance.product.model.ParameterMap.parameterMap at nl.paston.insurance.product.model.ParameterMap org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76) org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212) org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:149) org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:372) org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179) org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) javax.servlet.http.HttpServlet.service(HttpServlet.java:790) io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86) io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72) io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:282) io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:261) io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80) io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172) io.undertow.server.Connectors.executeRootHandler(Connectors.java:199) io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread.java:745)

I hope I have provided with all the information required. In this expert group of people, request you all to please help me in this issue. Any small help would be of greatest help to me. Thanks for your help in advance.

1

1 Answers

2
votes

Maps containing collections as values are a bit tricky; you need an adapter and classes for representing the map entries in a way JAXB can handle.

@XmlAccessorType(XmlAccessType.FIELD) 
public class ListOfEntry {
    @XmlElement
    private List<Entry> list = new ArrayList<>();
    public List<Entry> getList(){ return list; }
}

@XmlAccessorType(XmlAccessType.FIELD) 
public class Entry {
    @XmlElement
    private String key;
    @XmlElement
    private List<Parameter> list = new ArrayList<>();
    public String getKey(){ return key; }
    public void setKey( String value ){ key = value; }
    public List<Parameter> getList(){ return list; }
}

The Adapter does the transformations back and forth:

public class Adapter 
extends XmlAdapter<ListOfEntry, Map<String, List<Parameter>>> {
    @Override
    public Map<String, List<Parameter>> unmarshal(ListOfEntry loe)
        throws Exception {
        Map<String, List<Parameter>> map = new HashMap<>();
        for(Entry entry : loe.getList() ) {
            map.put(entry.getKey(), entry.getList() );
        }
        return map;
    }

    @Override
    public ListOfEntry marshal(Map<String, List<Parameter>> map)
        throws Exception {
        ListOfEntry loe = new ListOfEntry();
        for(Map.Entry<String, List<Parameter>> mapEntry : map.entrySet()) {
            Entry entry = new Entry();
            entry.setKey( mapEntry.getKey() );
            entry.getList().addAll( mapEntry.getValue() );
            loe.getList().add(entry);
        }
        return loe;
    }
}

And you must add an annotation to the Map field:

@XmlElement
@XmlJavaTypeAdapter(Adapter.class)
private Map<String, List<Parameter>> parameterMap = new HashMap<>();