Можно ли автоматически преобразовать результат запроса JPQL с несколькими типами объектов в формат JSON?

Я использую JPA Toplink, JAX-RS, NetBean6.9.

До сих пор я успешно конвертировал результат запроса JPQL, который представляет собой список с одним типом объекта, в JSON. Следующее работает нормально, он генерирует JSON к тому времени, когда он попадает в браузер, потому что я указал это в аннотации JPA.

Фрагмент JPA

@XmlRootElement //here enable JSON
@Entity
@Table(name = "MasatosanTest")

Фрагмент класса ресурсов

@Path("allJoin")
    @GET
    @Produces("application/json")
    public List<MasatosanTest> getAllJoinResult() {

        EntityManager em = null;
        List<Object[]> mt = null;

        try {
            em = EmProvider.getDefaultManager();

            Query query = em.createQuery("SELECT m1, m2 FROM MasatosanTest m1, MasatosanTest2 m2");

            mt = query.getResultList();
        }
        catch(Exception e) {
            System.out.println("MasatosanTestResource.java - getJoinedResult ERROR: " + e);
        }
        finally {
            if(em != null) {
                em.close();
            }
        }

        //I'm only adding MasatosanTest object into the List not MasatosanTest2
        List<MasatosanTest> list = new ArrayList<MasatosanTest>();
        MasatosanTest mt = null;
        for(Object[] items : mt) {
            mt = (MasatosanTest)items[0];
            list.add(mt);
        }
        return list;
    }//end getAllJoinResult()

Приведенный выше код в браузере выведет что-то вроде:

[MasatosanTest : [[name:foo], [name:moo]]

Моя проблема заключается в том, что когда JPQL возвращает два разных типа объектов, он больше не будет автоматически преобразовываться в JSON.

Если я немного изменю приведенный выше код, я также добавлю MasatosanTest2 в список.

 //Now I'm adding MasatosanTest2 to the List in addition to MasatosanTest
 //So changing List data type to List<Object> to accept both object types.
        List<Object> list = new ArrayList<Object>();
        MasatosanTest mt = null;
        MasatosanTest2 mt2 = null;
        for(Object[] items : mt) {

            mt = (MasatosanTest)items[0];
            mt2 = (MasatosanTest2)items[1];
            list.add(mt);
            list.add(mt2)
        }
        return list;

Затем, конечно, измените тип возврата метода на список.

 public List<Object> getAllJoinResult() {

Затем я получаю сообщение об ошибке, что это не может быть JSON :(

 A message body writer for Java type, class java.util.ArrayList, 
and MIME media type, application/json, was not found

Разрешено ли иметь JSON, который содержит несколько типов?

Моя цель - иметь JSON, например:

[[MasatosanTest : [[name:foo], [name:moo]],
[MasatosanTest2 : [[name:boo], [name:www]] ]

person Meow    schedule 24.12.2010    source источник
comment
Похоже, что когда 2 таблицы объединяются и возвращаются, функция формата JSON отключена (?), поскольку в одной из таблиц может быть не включен @XmlRootElement   -  person Meow    schedule 27.12.2010


Ответы (1)


После тестирования некоторых из них на основе онлайн-справки других людей я понял, что возвращаемый результат запроса равен List<Object[]>, а этот Object[] на самом деле Vector.

Итак, ниже выполнит эту работу (хотя и не уверен, что достаточно эффективен). Также JSONStringer взят из jettison api.

  List<Object[]> out = null;
  JSONStringer jstr = null;
  sb = new StringBuilder();
  Vector vec = null;
      for(Object item : out) {
          vec = (Vector)item;

          jstr = new JSONStringer();
          String json = jstr.object()
               .key("columnName1").value( vec.get(0) )
               .key("columnName2").value( vec.get(1) )
               .key("columnName3").value( vec.get(2) )
               .key("columnName4").value( vec.get(3) )
               .key("columnName5").value( vec.get(4) )
                    .endObject().toString();

                sb.append(json).append(",");
                jstr = null;//reset
       }

   sb.deleteCharAt(sb.length() - 1);
   System.out.println("====== json out result =====> " + sb.toString());
person Meow    schedule 27.12.2010