2015-04-13 21 views
2

我试图获取JAX RS资源以返回带有JSON对象的响应。当我通过资源类中的println()调用显示响应属性时,我发现MediaType已正确设置为“application/json”,并且存在与具有预期类型(SalesOrder),状态.FOUND),并且响应对象是OutboundJaxrsResponse的一个实例。但是,不管怎样,当浏览器(或Jersey客户端)收到响应时,这些响应属性似乎会被“替换”,并导致HTTP 500内部服务器错误。我的SalesOrder类用@XmlRootElement注释。Glassfish XML(或JSON)对HTTP 500内部服务器中的JAX-RS对象编组结果的响应错误

我的资源是这样的:

@GET 
@Path("{orderUid}") 
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) 
public Response getSalesOrder(@PathParam("orderUid") Integer orderUid) { 
    Response response = null; 
    System.out.println("Entering SalesOrderResource getSalesOrder()..."); 
    SalesOrder retrievedSalesOrder = salesOrderService.retrieveSalesOrder(orderUid); 
    System.out.println("Service called and found salesOrder Uid: " + retrievedSalesOrder.getSalesOrderUid()); 
    if (retrievedSalesOrder != null) { 
     System.out.println("SalesOrder found with UID: " + retrievedSalesOrder.getSalesOrderUid()); 
     response = Response.status(Status.FOUND).entity(retrievedSalesOrder).type(MediaType.APPLICATION_JSON).build(); 
     // The following readEntity call results in a Javax.ejb.EJBException ??? 
     // SalesOrder fetched = response.readEntity(SalesOrder.class); 
    } else { 
     response = Response.status(Status.NOT_FOUND).header("x-reason", "Order cannot be found").build(); 
    } 
System.out.println("Response status: " + response.getStatus()); 
System.out.println("Response status info: " + response.getStatusInfo()); 
System.out.println("Response class: " + response.getClass()); 
System.out.println("Response length: " + response.getLength()); 
System.out.println("Response media type: " + response.getMediaType()); 
System.out.println("Response entity: " + response.getEntity()); 
    return response; 
} 

...这会导致在运行时以下几点:

2015-04-12T18:08:21.803-0600 |信息:响应状态:302 2015-04-12T18:08:21.803-0600 |信息:响应状态信息:找到 2015-04-12T18:08:21.803-0600 |信息:响应类:class org.glassfish.jersey.message.internal.OutboundJaxrsResponse 2015-04-12T18:08:21.803-0600 |信息:响应长度:-1 2015-04-12T18:08:21.803-0600 |信息:响应媒体类型:application/XML 2015-04-12T18:08:21.803-0600 |信息:响应实体:[email protected]

的SalesOrder实体被定义为:

@Entity 
@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
@JsonIgnoreProperties({"subTotal", "userAccount"}) 
@Table(name="sales_order") 
@NamedQuery(name="SalesOrder.findAll", query="SELECT s FROM SalesOrder s") 
public class SalesOrder implements Serializable { 
private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name="SALES_ORDER_UID") 
private int salesOrderUid; 

@Column(name="ORDER_NUMBER") 
private String orderNumber; 

@Column(name="BILL_TO_CITY") 
private String billToCity; 

@Column(name="BILL_TO_FIRST_NAME") 
private String billToFirstName; 

@Column(name="BILL_TO_LAST_NAME") 
private String billToLastName; 

@Column(name="BILL_TO_STATE") 
private String billToState; 

@Column(name="BILL_TO_STREET_NAME") 
private String billToStreetName; 

@Column(name="BILL_TO_STREET_NUMBER") 
private String billToStreetNumber; 

@Column(name="BILL_TO_UNIT_NUMBER") 
private String billToUnitNumber; 

@Column(name="BILL_TO_ZIP_CODE") 
private int billToZipCode; 

@Column(name="CREDIT_CARD_CSV") 
private int creditCardCsv; 

@Temporal(TemporalType.TIMESTAMP) 
@Column(name="CREDIT_CARD_EXPIRATION_DATE") 
private Date creditCardExpirationDate; 

@Column(name="CREDIT_CARD_NUMBER") 
private String creditCardNumber; 

@Column(name="CREDIT_CARD_TYPE") 
private String creditCardType; 

@Column(name="EMAIL_ADDRESS") 
private String emailAddress; 

@Column(name="NAME_ON_CREDIT_CARD") 
private String nameOnCreditCard; 

@Temporal(TemporalType.TIMESTAMP) 
@Column(name="SALES_ORDER_DATE") 
private Date salesOrderDate; 

@Column(name="SALES_ORDER_STATUS") 
private String salesOrderStatus; 

@Column(name="SHIP_TO_CITY") 
private String shipToCity; 

@Column(name="SHIP_TO_STATE") 
private String shipToState; 

@Column(name="SHIP_TO_STREET_NAME") 
private String shipToStreetName; 

@Column(name="SHIP_TO_STREET_NUMBER") 
private String shipToStreetNumber; 

@Column(name="SHIP_TO_UNIT_NUMBER") 
private String shipToUnitNumber; 

@Column(name="SHIP_TO_ZIP_CODE") 
private int shipToZipCode; 

@Column(name="PROMO_CODE") 
private String promoCode; 

//Calculated and persisted for data retrieval performance 
@Column(name="SUB_TOTAL") 
private BigDecimal subTotal; 

@Column(name="DISCOUNT") 
private BigDecimal discount; 

@Column(name="SALES_TAX") 
private BigDecimal salesTax; 

@Column(name="SHIPPING") 
private BigDecimal shipping; 

@Column(name="TOTAL") 
private BigDecimal total; 

@Version 
@Column(name="LAST_UPDATED_TIME") 
private Timestamp lastUpdatedTime; 

//bi-directional many-to-one association to UserAccount 
@ManyToOne 
@JoinColumn(name="USER_ACCOUNT_UID") 
private UserAccount userAccount; 

@OneToMany(targetEntity=SalesOrderLine.class, mappedBy = "salesOrder", cascade = CascadeType.ALL) 
private List<SalesOrderLine> lineItems; 

public SalesOrder() { 
} 

... getter和setter

依赖于我的POM包括:

<dependency> 
     <groupId>javax.ws.rs</groupId> 
     <artifactId>javax.ws.rs-api</artifactId> 
     <version>2.0.1</version> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-annotations</artifactId> 
     <version>2.5.2</version> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-databind</artifactId> 
     <version>2.5.2</version> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.module</groupId> 
     <artifactId>jackson-module-jaxb-annotations</artifactId> 
     <version>2.5.2</version> 
    </dependency> 

不仅请求(http://localhost:8080/[myapp]/resources/salesOrders/13)导致HTTP 500内部服务器错误,但是当我尝试在资源内调用response.readEntity(SalesOrder.class)时,Glassfish服务器日志显示由java.lang.IllegalStateException导致的javax.ejb.EJBException警告:org上的出站消息不支持该方法。 glassfish.jersey.message.internal.OutboundJaxrsResponse.readEntity(OutboundJaxrsResponse.java:145)。

我认为SalesOrder对象的JAXB编组存在问题,但我无法确定根本原因。如果我简单地尝试以下操作,我仍然会收到HTTP 500内部服务器错误,指出XML和JSON编组都不会发生,但我认为这是内置到最新版本(GlassFish 4,JAX-RS 2)中的?

任何想法?

+0

您是否尝试过将请求类型设置为JSON? 'request.type(MediaType.APPLICATION_JSON).post(json,String.class);'?顺便说一下,你的代码在很多地方都是一团糟。 –

+0

仅供参考,那些杰克逊依赖不会被用作JAX-RS编组。你需要一个杰克逊的JAX-RS提供者,而不仅仅是杰克逊本身。 MOXY是Glassfish的默认设置,它很可能用于您的案例。如果你想使用Jackson,你需要添加[Jackson provider](https://jersey.java.net/documentation/latest/media.html#json.jackson),并注册'JacksonFeature',这样可以禁用MOXy 。 –

回答

0

我有类似的问题。可以肯定,检查你的日志显示是这样的:

重度:MessageBodyWriter找不到媒体类型=应用程序/ JSON, 类型= A类SalesOrder,genericType = A类SalesOrder。

如果是这样,问题是你没有注册杰克逊(或其他JSON作家供应商)。见泽西本节文档的说明:

https://jersey.java.net/documentation/latest/media.html#d0e7857

就我而言,我选择了杰克逊。我在我的pom.xml中添加了以下内容。

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>2.5.2</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.jaxrs</groupId> 
    <artifactId>jackson-jaxrs-json-provider</artifactId> 
    <version>2.5.2</version> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-json-jackson</artifactId> 
    <version>2.17</version> 
</dependency> 

然后,我有注册商:

public class Application extends ResourceConfig { 
    public Application() { 
     packages(<your ws package>); 
     register(JacksonFeature.class); 
    } 
} 
1

我想通了这个问题,并且将它张贴在这里为他人谋取利益。 1)我在资源方法中添加了以下内容: @Consumes(MediaType.TEXT_PLAIN) 2)步骤1在运行时导致以下错误: 在对象图中检测到循环。这将导致无限深的XML 3)错误导致我将@XmlTransient添加到与OneToMany,ManyToMany和ManyToOne中的其他实体相关的所有实体字段中。

现在我能够返回XML和JSON响应。

相关问题