似乎最新的JAX-RS可以处理将java.util.List作为XMLRootElement返回的方法,但普通的JAXB不能.我想模仿CXF和泽西岛正在做什么.
换句话说,我想列出一个名单,就像CXF和泽西岛一样.通常,如果您尝试使用JAXB封送列表,则会获得根元素异常.如何在不必制作包装物的情况下解决这个问题?
编辑:感谢您的答案,但我对@XmlElementWrapper非常熟悉,但这甚至不能模拟JAX-RS正在做的事情.
JAX-RS执行此操作:
@XmlRootElement(name="dog")
public class Dog {
private String name;
public String getName() { return this.name; }
//Setter also
}
Run Code Online (Sandbox Code Playgroud)
现在如果我序列化狗列表:
serialize(List<Dog> dogs);
Run Code Online (Sandbox Code Playgroud)
XML应该是(JAX-RS所做的):
<dogs>
<dog><name>Rascal</name></dog>
</dogs>
Run Code Online (Sandbox Code Playgroud)
所以你可以看到我不想为每个域对象创建一个包装器对象.
我理解它的方式是Java EE 6包括java.ws.rs(JAX-RS)的类,它们在JSR 311规范文档中定义.但是我不知道如果基类已经内置到Java EE 6中,为什么要使用Jersey或Apache CXF.难道你不能单独使用这些类创建RESTful Web服务吗?Jersey,Apache CXF等只是框架,使基于REST的Web服务的开发更容易吗?
我正在使用已经正常工作的JAX-RS上的Web服务.现在我正在寻找捕获一些异常的方法,以便向用户发送带有自定义消息的40X错误.
我有一个Web服务和一个ExceptionMapper.
这是我的网络服务:
@Path( value = "/test/")
public interface ServiceTest {
@Path(value = "{rrf}")
@GET
@Produces(MediaType.TEXT_XML)
public ObjectDTO getDealer(@PathParam("rrf") String rrf){
ObjectDTO objectDTO = new ObjectDTO();
if( verifyRRFSintax(rrf) ) {
//Get the objet, this part works fine
} else {
throw new IllegalArgumentException("Custom message");
}
return dwsDTO;
}
private boolean verifyRRFSintax(String rrf) {
return rrf.matches("[0-9]{8}");
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的ExceptionMapper
@Provider
@Produces(MediaType.TEXT_XML)
public class IllegalArgumentExceptionMapper
implements ExceptionMapper<IllegalArgumentException> {
@Override
public Response toResponse(IllegalArgumentException e) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
Run Code Online (Sandbox Code Playgroud)
这就是它在application-context.xml文件中的注册方式
<bean id="serviceTest" class="ServiceTest"/> …Run Code Online (Sandbox Code Playgroud) 我有一个复杂的Java接口层次结构,我想用JAXB编组(而不一定是unmarshal).这些接口表示将从JAX-RS REST API返回的对象,如XML,JSON,YAML等.(我正在使用RestEasy,它可以用XML以外的格式封送JAXB注释类型.)
问题似乎是JAXB基本上是面向类的.我已经对JAXB和接口的困难进行了大量的网络研究,最接近的解决方案是MOXy JAXB - 映射接口到XML和JAXB以及接口前端模型.但是,我有两个主要问题:a)我想在接口方面注释/工作,而不是具体类(其中将有多个实现并包含不应该被编组的重要其他状态),以及b)我有多级接口继承.这是接口的示例,减去目前为止的任何JAXB注释:
interface Uuided {
UUID getId();
}
interface Named {
String getName();
}
interface Component extends Uuided, Named {
Map<String, ComponentAttribute> getAttributes();
}
interface Attribute extends Named {
Type getType();
Object getValue();
}
interface ComponentAttribute extends Attribute {
Component getDeclaringComponent();
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,这会产生类似于:
<component id="xxx" name="thing">
<attributes>
<componentAttribute name="color">
<type><stringType/></type>
<value>green</value>
<declaringComponent idref="xxx"/>
</componentAttribute>
</attributes>
</component>
Run Code Online (Sandbox Code Playgroud)
显然,在摘要中,这导致了诸如确定最衍生的带注释的接口之类的问题,理论上可以有多个接口.但是,在我的情况下,我认为具体类只实现了一个应该被封送的单个接口.解组不是必需的,因为我有单独的类定义upsert属性.
所以我的问题是,这甚至可以用JAXB来处理,如果是这样,怎么样?即使我必须非常明确地定义绑定,适配器等,我也希望在JAXB框架内工作以获得RestEasy中所有非XML提供程序的好处.
在Java中我使用的时候
@Produces("application/json")
Run Code Online (Sandbox Code Playgroud)
注释输出不会形成人类可读的形式.我怎么做到这一点?
我使用Jersey来实现JAX-RS REST样式服务以及用于JSON映射的Jackson 2.0.2.其中一个REST服务返回一个List<EntityA>(让我们称之为indexA)EntityA包含List<EntityB>另一个服务,而另一个服务只返回一个List<EntityB>(让我们称之为indexB):
@Entity
@JsonAutoDetect
public class EntityA {
@Id
private String id;
@OneToMany
private List<EntityB> b;
...
}
@Entity
@JsonAutoDetect
@JsonFilter("bFilter")
public class EntityB {
@Id
private String id;
private String some;
private String other;
private String attributes;
...
}
@Path("/a")
public class AResource {
@GET
@Path("/")
public List<EntityA> indexA() {
...
}
}
@Path("/b")
public class BResource {
@GET
@Path("/")
public List<EntityB> indexB() {
...
} …Run Code Online (Sandbox Code Playgroud) 我一直在寻找,但似乎无法找到一个明确的答案......
服务器(我的问题的玻璃鱼)注入用@Context注释的实际objets的机制是什么?更具体地说,如果我想编写一个类似于以下内容的类:
@Path("/")
public class MyResource {
@GET
public String doSomething(@Context MyObject obj) {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
那我该怎么办?MyObject在哪里实现,谁在实现它,以及如何实现?
编辑:我见过以下内容:
在JAX-RS中使用@ Context,@ Extider和ContextResolver
http://jersey.576304.n2.nabble.com/ContextResolver-confusion-td5654154.html
但是,这与我所看到的不一致,例如在org.neo4j.server.rest.web.RestfulGraphDatabase的构造函数中,它具有以下签名:
public RestfulGraphDatabase(
@Context UriInfo uriInfo,
@Context Database database,
@Context InputFormat input,
@Context OutputFormat output,
@Context LeaseManager leaseManager )
Run Code Online (Sandbox Code Playgroud) 什么是Resteasy?RESTEasy和JAX-RS有什么区别?@PathParam和之间有什么区别@QueryParam?
我有一个基于json的REST Web服务实现使用:Jetty,Jersey,Jersey-JSON使用Jackson.
我的一个方法接收一个Person实例,它有一个List <String>类型的字段.即:
Public class Person {
List<String> names;
}
Run Code Online (Sandbox Code Playgroud)
如果我用一系列名字来称呼它,一切正常!例如:
{ "names" : [ "Jhon", "Doe" ] }
Run Code Online (Sandbox Code Playgroud)
但是如果这个人只有一个名字,我的客户就会创建一个单独的值元素,例如:
{ "names" : "Jhon" }
Run Code Online (Sandbox Code Playgroud)
当我尝试使用单个值调用服务时,我得到一个例外:
Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token
Run Code Online (Sandbox Code Playgroud)
题:
我应该如何创建/配置我的Web服务,以便能够在将数组字段作为单个元素发送给我时反序列化数组字段.
-
我已经读过:
和
这是指最后一个答案:
Jersey客户端无法反序列化json服务 - 异常(无法反序列化实例)
但这些都没有解决问题.
先感谢您!
我正在研究在Glassfish上运行的应用程序.我应该通过使用jax-rs和jersey将servlet转换为适当的restful内容.
我一直试图找到init()方法的解决方法,但直到现在我都失败了.
这是原始部分,使用servlet:
import javax.servlet.*
public void init(ServletConfig config) throws ServletException {
super.init(config);
if (!isRunning() == true)) {
/* Do some stuff here*/
}
logger.info("Deamon has started");
}
Run Code Online (Sandbox Code Playgroud)
而这个我试图使用jax-rs
import javax.ws.rs.*
import javax.servlet.*
public void init(@Context ServletConfig config) throws ServletException {
//uper.init(config);
if (!isRunning() == true)) {
/* Do some stuff here*/
}
logger.info("Deamon has started");
}
Run Code Online (Sandbox Code Playgroud)
我检查过邮件列表并用Google搜索,但无法找到适用于此案例的方法.
任何想法如何使用servlet为init方法实现相同的行为?