Как мне настроить класс POJO, чтобы он мог использоваться в качестве ресурса в службе отдыха JAX-RS? (Liferay 7.1)
Я могу использовать объект String в службе отдыха JAX-RS, но не могу использовать объект POJO. Как мне настроить класс POJO, чтобы он мог использоваться в качестве ресурса в службе отдыха JAX-RS?
Класс DTO
public class RestServiceDTO {
private String groupId;
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId)
this.groupId = groupId;
}
@Override
public String toString() {
return "RestServiceDTO [groupId=" + groupId + "]";
}
}
Служба отдыха:
@Component(
immediate = true,
property = {
JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE + "=/greetings",
},
service = Application.class
)
public class RestServiceApplication extends Application {
public Set<Object> getSingletons() {
return Collections.<Object>singleton(this);
}
@POST
@Path("/post")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public String test(RestServiceDTO dto) {
String groupid = dto.getGroupId();
return "{'groupid':'" + groupid + "'}";
}
}
Ошибка:
2019-02-12 13: 33: 58.021 ОШИБКА [http-nio-8080-exec-1][JAXRSUtils:83] Не найдено устройство чтения тела сообщения для класса com.dto.RestServiceDTO, ContentType: application/json
1 ответ
Начиная с версии 7.1 Liferay поддерживает спецификацию OSGi JAX-RS Whiteboard, что означает поддержку JAX-RS 2.1 с использованием CXF, что также означает, что существует поддержка JAXB-объектов POJO с аннотациями.
Если вам нужно вернуть простой POJO, вы обычно будете в порядке, просто аннотируя свой класс POJO с помощью @XmlRootElement
.
Убедитесь, что вы получили поддержку времени выполнения JAXB, прикрепленную к вашему приложению, потребовав ее в конфигурации вашего компонента приложения, поместив свойство osgi.jaxrs.extension.select=(osgi.jaxrs.name=jaxb-json)
на вашем прикладном компоненте.
Это свойство укажет доске JAX-RS не запускать ваше приложение, пока расширение не будет установлено и не будет готово для вашего приложения.
Начиная с Liferay 7.2 реализация JAXB по умолчанию была изменена на Jackson. Изменения конфигурации не требуется, но теперь каждый POJO может быть сериализован в JSON, даже если POJO не аннотирован. Просто убедитесь, что к вашему приложению подключена поддержка времени выполнения jaxb, как указано выше.
И в 7.1, и в 7.2 вы можете проверить статус ваших приложений JAX-RS и прикрепленных расширений, используя команду оболочки gogo jaxrs:check
Liferay использует реализацию JAX-RS Apache CXF. Как упомянуто в комментариях @dkb, вы должны предоставить аннотацию, которая есть у вас в примере кода.
Вам нужно добавить зависимости. Посмотрите список ниже и обратите внимание, что некоторые из них предоставляются платформой, но некоторые должны быть включены в ваш jar-файл и не забывайте о переходных зависимостях.
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
<version>3.0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.7.9</version>
</dependency>
Последнее, что есть. Вам необходимо зарегистрировать своего провайдера Jackson в приложении JAX-RS. Это делается, например, в классе приложений (есть больше способов сделать это).
@Override
public Set<Object> getSingletons() {
Set<Object> singletons = new HashSet<>();
singletons.add(getJacksonProvider());
return Collections.unmodifiableSet(singletons);
}
Добавить зависимость для MAVEN:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.10</version>
</dependency>
для GRADLE:
compileOnly group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.9.10'
теперь добавьте этот метод в свой класс Apllication
private JacksonJsonProvider getJacksonJsonProvider() {
JacksonJsonProvider jacksonJsonProvider = new JacksonJsonProvider();
ObjectMapper objectMapper = new ObjectMapper();
// Prevent serialization of null and empty string values
objectMapper.setSerializationInclusion(Include.NON_EMPTY);
jacksonJsonProvider.setMapper(objectMapper);
jacksonJsonProvider.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return jacksonJsonProvider;
}
теперь измените код getSingletons()
метод вашего класса приложения для
@Override
public Set<Object> getSingletons() {
Set<Object> singletons = new HashSet<>();
singletons.add(this);
singletons.add(getJacksonJsonProvider());
return Collections.unmodifiableSet(singletons);
}
теперь я думаю, тебе нужно сменить return
заявление к
return Response.ok(JSONFactoryUtil.looseSerializeDeep("{'groupid':'" + groupid + "'}"), MediaType.APPLICATION_JSON).build();
но я не уверен, что вам нужно изменить свой оператор возврата, иначе ваш будет работать нормально