JAX-RS отменяет вызов с помощью @XmlIDREF - PullRequest
2 голосов
/ 22 сентября 2011

Я уже часами изучаю эту проблему, возможно, просто, но я ее больше не понимаю:

У меня есть сущность (Param), которая отображается в json через jax-rs.Сущность ссылается на другую сущность (шаг).Когда я пишу / читаю json, я не хочу видеть всю пошаговую сущность, а просто ее идентификатор, поэтому я использую этот код:

@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Param implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
long id;
@Column(name = "KEYNAME")
String key;
String value;
@XmlIDREF
Step step;  
}

Отлично работает для маршаллинга.-request показывает мне что-то следующее:

{id: 1,
key: "a",
value: "b",
step: 53
}

Но когда я публикую некоторый параметр на сервере, он не может отобразить числовой идентификатор шага-сущности.

Мне нужно предоставить unmarshaller собственный IDResolver.Но как я могу настроить unmarshaller ????Сервлет Jax-RS делает сортировку для меня.Мой код выглядит так:

@Path("param")
public class ParamRepresentation {

  /**
   * Retrieves representation of an instance of ParamRepresentation
   * @return an instance of Param
   */
  @GET
  @Produces("application/json")
  @Path("{ID}")
  public Param getJson(@PathParam("ID") long id) {
    return (Param) ctr.find(id, Param.class);
}


@PUT
@Path("{ID}")
@Consumes("application/json")
@Produces("application/json")
public SuccessMessage updateStep(@PathParam("ID") long id, Param p) {
    ctr.update(p);
    ParamSuccessMessage sm = new ParamSuccessMessage();
    sm.setSuccess(true);
    sm.setParam(p);
    return sm;
}
}

Так как я могу настроить unmarshaller ?????

Ответы [ 2 ]

1 голос
/ 05 октября 2011

Я проделал аналогичную работу с использованием представлений в Джерси и XML.Я использовал адаптер xml для симметричного отображения между полным дочерним элементом и частичным (просто id) элементом.

Я бы аннотировал сущность Step в вашей сущности Param следующим образом:

//javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter
@XmlJavaTypeAdapter(PartialStepEntityAdapter.class)
Step step

Затем вам нужно будет определить частичную сущность Step и Адаптер.PartialStep будет идентичным вашему исходному классу шага, но только с полем id.

PartialStepEntityAdapter будет отображать Step в PartialStep при маршалинге и PartialStep вStep при демаршаллинге:

//javax.xml.bind.annotation.adapters.XmlAdapter
public class PartialStepEntityAdapter extends XmlAdapter<PartialStep, Step> {

    @Override
    public Step unmarshal(PartialStep partialStep) throws Exception {
        Step step = new Step();
        step.setId(partialStep.getId());

        return step;
    }

    @Override
    public PartialStep marshal(Step step) throws Exception {
        PartialStep partialStep= new PartialStep();
        partialStep.setId(step.getId());

        return partialStep;
    }
}

Надеюсь, это поможет.

1 голос
/ 23 сентября 2011

Я думаю, вы неправильно поняли цель IDREF в схемах XML.Он позволяет вам ссылаться на другой элемент, помеченный как идентификатор (т. Е. С пометкой @XmlID в JAXB) * ​​1002 * в том же документе .Вы не можете использовать его для ссылки на идентификатор в другом месте в мире;для этого вы бы использовали URI (возможно, с частью идентификатора фрагмента).Чтобы сделать эти в JAXB, вы используете:

@XmlElement    // You might be able to omit this part; it's here for clarity
@XmlSchemaType(name = "anyURI")
public URI exampleField;

Затем вам нужно выяснить, относится ли URI к чему-то, что вы знаете (т. Е. Разрешить URI и посмотреть, указывает ли оно насамостоятельно) и разобраться с идентификатором фрагмента.Или сделайте более распространенный трюк - просто используйте строку и не беспокойтесь о попытке магическим образом соединить все в связующем слое.(Это работает довольно хорошо на практике.)

...