5 Replies Latest reply on Jan 7, 2010 10:47 AM by lvdberg

    Resteasy and JAXB: decide which xml properties to marshall

    demetrio812

      Hi,
      I'm giving a try to resteasy, everything works pretty well but I'm stuck on finding a good way to solve a very simple problem.


      In my test I have a News entity which contains a title and a long description:



      @Entity
      @Table(name = "news", catalog = "ifandango1")
      @XmlRootElement
      @XmlAccessorType(XmlAccessType.NONE)
      public class News implements java.io.Serializable {
      
              private Integer id;
              private String title;
              private String description;
      
              public News() {
              }
      
      
              @Id
              @GeneratedValue(strategy = IDENTITY)
              @Column(name = "id", unique = true, nullable = false)
              @XmlAttribute
              public Integer getId() {
                      return this.id;
              }
      
              public void setId(Integer id) {
                      this.id = id;
              }
      
              @Column(name = "title", nullable = false)
              @NotNull
              @XmlAttribute
              public String getTitle() {
                      return this.title;
              }
      
              public void setTitle(String title) {
                      this.title = title;
              }
      
              @Column(name = "description", nullable = false, length = 65535)
              @NotNull
              @Length(max = 65535)
              @XmlElement
              public String getDescription() {
                      return this.description;
              }
      
              public void setDescription(String description) {
                      this.description = description;
              }
      
      }



      Then I have a Seam component that produces the XML:




      @Name("newsRestResource")
      @Scope(ScopeType.EVENT)
      @Path("/news")
      public class NewsResource {
      
          @In(create = true)
          EntityManager entityManager;
      
          @In(create = true)
          NewsList newsList;
      
          @GET
          @Path("/data/{id}")
          @Produces("application/xml")
          public News getData(@PathParam("id") int id) {
              News news = entityManager.find(News.class, id);
              return news;
          }
      
          @GET
          @Path("/list")
          @Produces("application/xml")
          public News[] getList() {
              newsList.setOrderColumn("news.ordering");
              newsList.setOrderDirection("asc");
              newsList.setRestrictionLogicOperator("and");
              final News[] result = newsList.getResultList().toArray(new News[]{});
      
              return result;
          }
      
      }



      Everything works but I would like that the xml list of the news doesn't contain the description field, is it possible using the annotations?


      I looked on the net all the morning but never find a real example of that (isn't it a frequent use case?)


      The only thing I tried is using another Entity for the same db table but I don't like this approach at all, I'm sure it is possible in a very simple way.


      Any hint?


      Thanks!


      Dem


        • 1. Re: Resteasy and JAXB: decide which xml properties to marshall

          Hi,


          You can try just put the @XmlRootElement on the News class, no other annotations, see if that works, my part for the xml works fine


          • 2. Re: Resteasy and JAXB: decide which xml properties to marshall
            demetrio812

            Yeah but the result would be the same (you can use @XmlAccessorType(XmlAccessType.NONE) to specify that you don't want all fields to be automatically serialized and want to specify which one to).


            What I would like to do is to specify 2 different binding excluding the description from the second one.


            Anyone knows the best way to do that?


            Thanks


            Dem

            • 3. Re: Resteasy and JAXB: decide which xml properties to marshall
              lvdberg

              Hi,


              It's a bit tricky because you're using the same class for marshalling as for persistency, but it can be done with an additional layer.

              One way to do this is to create your an additional set of java-objects only for Marshalling. You create the XML-Schema first and define the description as an optional attribute, create the classes with the XJC-compiler and use the class for marshalling. When you create an object, you can leave out the description and it will not be included in the marshalling proces.


              A bit more laborious, but it worked for me.


              Leo

              • 4. Re: Resteasy and JAXB: decide which xml properties to marshall
                demetrio812

                Hi Leo,


                thanks for your answer, what I wanted to avoid was to introduce another layer, now it is a test and it's ok, but in a real environment I will have to maintain the double of classes, then if some requirement changes into the model I have also to change the classes for marshalling.


                Also using the same object for db and xml avoids me to copy the data between 2 different objects with the same structure (it remembers me the EJBs and JSF managed beans and the reason why Seam has been introduced) and I'll have to maintain that code as well.


                I'm not sure this is a productive way if your XML schema is very close to the model.


                What do you think?


                dem

                • 5. Re: Resteasy and JAXB: decide which xml properties to marshall
                  lvdberg

                  Hi,


                  We have found that marshalling to XML usually uses different classes, caused by the differences in structure. The same mismatch you see for persistency in a DB you see for XML as well. The quick and dirty method of fully annotating your domain model for validating, persistency, marshalling etc. works nice until you stumble on something more complex. In our case it was the deep referencing of Java-objects (for instance to themself) which leads to easy to marshall beans, where handcrafted code is necessary. We needed to flatten the model to get a  XML-tree to be really useable.


                  On the other hand, the XMLAttribute annotation has a required, attribute. I don't know if this has the same effect with a null value.


                  RestEsay combined with Seam is really great, but is has some drawbacks such a you mention, you could always decide to extend the existing marshallers which is really not complex with the functionality provided by JAXB.


                  Leo