2017-01-04 8 views
1

я реализовал следующие REST вызова:Почему возникает ошибка NoMessageBodyWriterFoundFailure?

@Path("/widgets") 
public class WidgetResource { 

    @GET 
    @Produces("application/x-protobuf") 
    public WidgetsProtoc.WidgetList getAllWidgets() { 
     Widget widget1 = 
      Widget.newBuilder().setId("1").setName("widget 1").build(); 
     Widget widget2 = 
      Widget.newBuilder().setId("2").setName("widget 2").build(); 
     WidgetsProtoc.WidgetList list = WidgetsProtoc.WidgetList.newBuilder().addWidget(widget1).addWidget(widget2).build(); 
     return list; 
    } 
} 

Также класс поставщика, который обеспечивает и потребляет применение/х-Protobuf:

@Provider 
@Produces("application/x-protobuf") 
@Consumes("application/x-protobuf") 
public class ProtobufMessageWriter implements MessageBodyWriter<WidgetsProtoc.WidgetList>, MessageBodyReader<WidgetsProtoc.WidgetList> { 

    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 
     return WidgetsProtoc.WidgetList.class.isAssignableFrom(type); 
    } 

    @Override 
    public long getSize(WidgetsProtoc.WidgetList widgetList, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 
     return widgetList.getSerializedSize(); 
    } 

    @Override 
    public void writeTo(WidgetsProtoc.WidgetList widgetList, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { 
     entityStream.write(widgetList.toByteArray()); 
    } 

    @Override 
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 
     return type.isAssignableFrom((Class<?>) genericType); 
    } 

    @Override 
    public WidgetsProtoc.WidgetList readFrom(Class<WidgetsProtoc.WidgetList> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { 
     try { 
     Method newBuilder = type.getMethod("newBuilder"); 
     GeneratedMessage.Builder<?> builder = (GeneratedMessage.Builder<?>) newBuilder.invoke(type); 
     return (WidgetsProtoc.WidgetList) builder.mergeFrom(entityStream).build(); 
     } catch (Exception e) { 
     throw new WebApplicationException(e); 
    } 
    } 
} 

Мой pom.xml выглядит следующим образом:

<?xml version="1.0"?> 
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"> 
<modelVersion>4.0.0</modelVersion> 
<groupId>com.mkyong.common</groupId> 
<artifactId>RESTfulExample</artifactId> 
<packaging>war</packaging> 
<version>1.0-SNAPSHOT</version> 
<name>RESTfulExample Maven Webapp</name> 
<url>http://maven.apache.org</url> 
<repositories> 
    <repository> 
     <id>JBoss repository</id> 
     <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url> 
    </repository> 
</repositories> 
<dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.8.2</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.jboss.resteasy</groupId> 
     <artifactId>resteasy-jaxrs</artifactId> 
     <version>3.1.0.Final</version> 
    </dependency> 
    <dependency> 
     <groupId>org.jboss.resteasy</groupId> 
     <artifactId>resteasy-jackson-provider</artifactId> 
     <version>3.1.0.Final</version> 
    </dependency> 
    <dependency> 
     <groupId>com.google.protobuf</groupId> 
     <artifactId>protobuf-java</artifactId> 
     <version>3.1.0</version> 
    </dependency> 
    <dependency> 
     <groupId>org.jboss.resteasy</groupId> 
     <artifactId>resteasy-jettison-provider</artifactId> 
     <version>3.0.11.Final</version> 
    </dependency> 
    <dependency> 
     <groupId>org.jboss.resteasy</groupId> 
     <artifactId>resteasy-jaxb-provider</artifactId> 
     <version>3.1.0.Final</version> 
    </dependency> 
    <dependency> 
     <groupId>com.sun.jersey</groupId> 
     <artifactId>jersey-spring</artifactId> 
     <version>1.0</version> 
    </dependency> 
    <dependency> 
     <groupId>com.google.guava</groupId> 
     <artifactId>guava</artifactId> 
     <version>20.0</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-servlet-core</artifactId> 
     <version>2.15</version> 
    </dependency> 
    <dependency> 
     <groupId>org.codehaus.jackson</groupId> 
     <artifactId>jackson-mapper-asl</artifactId> 
     <version>1.9.13</version> 
    </dependency> 
    <dependency> 
     <groupId>com.sun.jersey</groupId> 
     <artifactId>jersey-json</artifactId> 
     <version>1.19.3</version> 
    </dependency> 
</dependencies> 
<pluginRepositories> 
    <pluginRepository> 
     <id>protoc-plugin</id> 
     <url>https://github.com/xolstice/protobuf-maven-plugin</url> 
    </pluginRepository> 
</pluginRepositories> 

<build> 
    <finalName>RESTfulExample</finalName> 
    <plugins> 
     <plugin> 
      <groupId>org.xolstice.maven.plugins</groupId> 
      <artifactId>protobuf-maven-plugin</artifactId> 
      <version>0.5.0</version> 
      <configuration> 
       <protocExecutable>C:\Users\DevUser\Downloads\protoc-3.1.0-win32\bin\protoc</protocExecutable> 
      </configuration> 
      <executions> 
       <execution> 
        <goals> 
         <goal>compile</goal> 
        </goals> 
       </execution> 
      </executions> 
     </plugin> 
     <plugin> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <configuration> 
       <source>1.6</source> 
       <target>1.6</target> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

мои виджеты.прото:

вариант java_package = "пример"; опция java_outer_classname = "WidgetsProtoc";

message Widget { 
required string id = 1; 
required string name = 2; 
} 

message WidgetList { 
repeated Widget widget = 1; 
} 

Для http://localhost:8080/RESTfulExample/widgets я получаю следующее сообщение об ошибке:

Не удалось найти MessageBodyWriter для объекта ответа типа: hu.example.WidgetsProtoc $ WidgetList типа носителя: применение/х-Protobuf

Моя структура: в ИПВ-основного Java-пакета, например, где классы Java являются (поставщик и класс REST) ​​ в src-main-proto-> .proto class src-main-webapp-WEB-INF файл web.xml , и я развернул файл войны в WildFly.

Я не знаю, почему я получил это сообщение, я попытался написать еще один метод для jsos, и он работает.

ответ

0

Похоже, что ваш аннотированный класс провайдера неизвестен контексту JAX-RS, который является resteasy для этого случая.

Так как повторная реализация и другие реализации JAX-RS имеют встроенную поддержку сериализации/десериализации json, ваш json-тест, безусловно, работает.

Согласно документации Jboss;

Спецификация JAX-RS позволяет подключать собственный считыватель и автоответчик для чтения и ответа. Для этого вы комментируете класс с @Provider и задаете типы @Produces для типов writer и @Consumes для читателя. Вы также должны реализовать интерфейс MessageBodyReader/Writer соответственно. Вот пример.

Restaasy ServletContextLoader автоматически сканирует ваши каталоги WEB-INF/lib и классов для классов, аннотированных с помощью @Provider, или вы можете вручную настроить их в web.xml. См. Установка/Конфигурация

Прежде всего, добавьте необходимые записи в свой класс @Provider и дважды проверьте, существует ли вложенное базовое исключение, которое вызывает загрузку/инициализацию класса.

Также добавьте конфигурацию в свой web.xml для вашего класса поставщика в качестве обходного пути для обхода (если есть) проблем автосканирования.

<context-param> 
<param-name>resteasy.providers</param-name> 
<param-value>hu.example.ProtobufMessageWriter</param-value> 
</context-param> 

И, наконец, трассировка стека исключения может также помочь, если вы можете предоставить.

+0

Спасибо большое :) это работает :) – seherez

+0

ну, приятно знать :) – Gladmir