Как вернуть вывод XHTML из Apache Wink с помощью JSP?

До сих пор мне удавалось настроить базовую веб-службу с помощью Apache Wink. Это включает возврат типов мультимедиа Atom, JSON, HTML, XHTML, XML и открытого текста в соответствии с предоставленными примерами. Мне также удалось успешно использовать MessageBodyWriter для "ручной" генерации вывода XHTML. Пока отлично. Я рад вернуть большинство типов мультимедиа через существующий механизм Wink.

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

@Path("{id}")
@GET
@Produces({MediaType.APPLICATION_XHTML_XML})
public Response getXhtml( @PathParam("id") String id )
{
    try { 
        MyBean mybean = service.getBean(id);
        return Response.ok(new MyAsset(mybean))
                .location(new URI(baseurl+"Output.jsp"))
                .type(MediaType.APPLICATION_XHTML_XML).build();
    } catch ( Exception e ) {
        throw new WebApplicationException(e,Status.INTERNAL_SERVER_ERROR);
    }
}

Просто кажется, что JSP полностью игнорируется. И если я, наконец, выясню, как это сделать, мне нужно будет знать, как передать POJO в качестве параметра. Я знаю, что мне здесь чего-то не хватает, поскольку я предполагаю, что Apache Wink может взаимодействовать с веб-службой на основе JSP. Документация Wink в целом хороша, но я ничего не нашел по этому поводу. Спасибо за любую помощь, в идеале ссылку на рабочий пример.


person Ichiro Furusato    schedule 08.07.2012    source источник


Ответы (2)


Нет встроенного механизма для передачи POJO в качестве параметра. Вам нужно создать URI самостоятельно. Кроме того, я думаю, вы хотите отправить перенаправление на свой jsp, а не только на 200 OK. Итак, вы можете сделать что-то вроде этого:

@Path("{id}")
@GET
@Produces({MediaType.APPLICATION_XHTML_XML})
public Response getXhtml( @PathParam("id") String id )
{
    try { 
        MyBean mybean = service.getBean(id);
        return Response.seeOther(UriBuilder.fromUri(baseurl+"Output.jsp")
                 .replaceQuery(convertMyBeanToQuery(mybean)).build())
                .type(MediaType.APPLICATION_XHTML_XML).build();
    } catch ( Exception e ) {
        throw new WebApplicationException(e,Status.INTERNAL_SERVER_ERROR);
    }
}

Вам нужно реализовать convertMyBeanToQuery для построения строки запроса: key=value&key1=value

Вы также можете использовать UriBuilder.queryPatam для добавления параметров один за другим.

person Tarlog    schedule 08.07.2012
comment
Привет, спасибо за ваш ответ. Возврат вывода в URI означает, что мы будем вынуждены раскрывать все выходные параметры в строке URI (т. е. отображаться в адресной строке браузера пользователя), а не скрывать эту информацию при обмене данными между веб-службой и JSP. Это не кажется очень успокаивающим и, что более важно, раскрывает некоторую личную информацию, которую мы хотим хранить исключительно между службой и JSP. - person Ichiro Furusato; 09.07.2012
comment
Вы также можете вернуть его в заголовках и получить доступ к заголовкам из jsp. Таким образом, личная информация не будет отображаться в URL-адресе. - person Tarlog; 09.07.2012

В конце концов я нашел решение, поэкспериментировав с некоторыми идеями, полученными при просмотре примера Wink DefectAsset. Подсказкой стал класс HtmlDescriptor, который находится во внутреннем API Wink.

Я предоставляю свой bean-компонент в качестве аргумента в конструкторе Asset (т. е. класс с аннотацией «@Asset»), а затем передаю Asset через JSP непосредственно как сущность в ответе:

MyBean mybean = service.getBean(id);
return Response.seeOther(new URI(baseurl+"Output.jsp"))
        .entity(new MyAsset(bean))
        .type(MediaType.APPLICATION_XHTML_XML).build();

Для этого требуется метод в MyAsset.java:

@Produces({MediaType.APPLICATION_XHTML_XML})
public HtmlDescriptor getHtml()
{
    return new HtmlDescriptor(bean,"/Output.jsp","MyBeanPayload");
}

а в Output.jsp я получаю доступ к bean-компоненту через имя атрибута, указанное в качестве третьего аргумента в конструкторе HtmlDescriptor:

<%
  MyBean bean = (MyBean)request.getAttribute("MyBeanPayload");
  String id = bean.getId();
%>

В JSP я использую возвращаемые значения в форме HTML, поэтому я избегаю их, используя StringEscapeUtils.escapeHtml(). Возвращаемый URI не включает ничего, кроме пути RESTful с добавлением «?alt=application%2Fxhtml%2Bxml», который используется для указания типа носителя.

Кажется, это демонстрирует, как передать POJO в выходной JSP через Apache Wink.

person Ichiro Furusato    schedule 09.07.2012
comment
Это решение будет работать только в том случае, если jsp и ваше приложение REST являются одним и тем же веб-приложением на одном сервере. - person Tarlog; 09.07.2012
comment
В этом проекте JSP являются частью одного и того же веб-приложения, но я понимаю вашу точку зрения. Я мог бы попробовать использовать подход с заголовком HTTP, который вы упомянули выше, чтобы увидеть, как это работает. Спасибо за вашу помощь! - person Ichiro Furusato; 10.07.2012