部署自定义域时,JAX-RS无法正常工作

时间:2014-06-04 09:24:01

标签: java-ee jaxb glassfish jax-rs jaas

我在Glassfish 4.0上部署了一个有效的JAX-RS Web服务:

@POST
@Path("authenticate")
@Produces(MediaType.APPLICATION_XML)
public XmlUser authenticate(@FormParam("email") final String email, @FormParam("password") final String password) {
    User user = getUserByEmailOrUsername(email, email);
    if (user == null) {
        return null;
    }
    return mapUserToXmlUser(user);
}

然后我部署了一个自定义域并且Web服务停止工作,抛出以下异常:

javax.servlet.ServletException: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/xml, type=class com.mycompany.api.XmlUser, genericType=class com.mycompany.api.XmlUser.

我怀疑这与Jersey的冲突版本有关,但我不确定。 在Web服务war模块中,我正在使用此依赖项:

<dependency>
  <groupId>javax</groupId>
  <artifactId>javaee-api</artifactId>
  <version>7.0</version>
</dependency>

在realm jar文件中,我必须使用以下内容(以便能够扩展com.sun.appserv.security.AppservRealm),我怀疑它与以前的依赖项冲突:

<dependency>
  <groupId>org.glassfish.main.common</groupId>
  <artifactId>glassfish-ee-api</artifactId>
  <version>4.0</version>
  <scope>provided</scope>
</dependency>

如果我取消部署该域,则Web服务将再次开始工作。

编辑: 如果我在没有我的JAXB类XmlUser(它应该由Web服务和我的领域,客户端使用)的情况下部署领域,那么Web服务将再次运行。但由于领域应该使用Web服务进行用户查找,因此我必须包含该类文件。这就是生成的JAXB类的样子:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "User", propOrder = {
    "name",
    "email",
    "username",
    "password",
    "languageCode",
    "lastLogin",
    "userType"
})
@XmlRootElement(name = "User")
public class XmlUser {

    @XmlElement(name = "Name")
    protected String name;
    @XmlElement(name = "Email")
    protected String email;
    @XmlElement(name = "Username")
    protected String username;
    @XmlElement(name = "Password")
    protected String password;
    @XmlElement(name = "LanguageCode")
    protected String languageCode;
    @XmlElement(name = "LastLogin", type = String.class)
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "dateTime")
    protected Calendar lastLogin;
    @XmlElement(name = "UserType", required = true)
    protected String userType;

    // Getters and setters...
}

1 个答案:

答案 0 :(得分:0)

正如错误消息明确指出的那样,它无法找到媒体类型MessageBodyWriter和类application/xml的{​​{1}}。

这意味着,Jersey(GlassFish上的JAX-RS impl)希望发送带有com.mycompany.api.XmlUser对象的消息,但它不知道如何将此对象转换为XML(同样适用于明文和JSON)。

有多种方法可以解决这个问题:

如果您的XmlUser课程注明XmlUser,则应该开箱即用。如果你有这个并且无论如何都会得到这个错误,可能会有一些缺少的Jersey依赖。

您可以为@XmlRootElement(name = "XmlUser")课程提供MessageBodyWriter。您基本上必须实现类似于此的接口XmlUser

MessageBodyWriter<XmlUser>

public class XmlUserMessageBodyWriter implements MessageBodyWriter<XmlUser> { @Override public boolean isWriteable(Class<?> type, Type type1, Annotation[] antns, MediaType mt) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public long getSize(XmlUser user, Class<?> type, Type type1, Annotation[] antns, MediaType mt) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void writeTo(XmlUser t, Class<?> type, Type type1, Annotation[] antns, MediaType mt, MultivaluedMap<String, Object> mm, OutputStream out) throws IOException, WebApplicationException { } } 方法中,您必须构造XML并将其写入OutputStream writeTo,这是一个非常基本的示例:

out

您可以在Jersey docs chapter 7: JAX-RS Entity Providers

中找到更多详细信息

另见:

相关问题