2010-01-14 23 views
26

Tôi đang sử dụng JAX WS để hiển thị một WebService. Một số hoạt động của dịch vụ này có thể tạo ra ngoại lệ. Không phải ngoại lệ máy chủ nội bộ, mà là ngoại lệ phụ thuộc vào các đối số đầu vào của lời gọi hoạt động.JAX-WS - Bản đồ Ngoại lệ đối với lỗi

Nếu tôi xác định rằng hoạt động của tôi ném một ngoại lệ tùy chỉnh, như vậy:

@WebService 
@SOAPBinding(style = Style.RPC, use = Use.LITERAL) 
public class MyServiceEndpointImpl implements MyServiceEndpoint { 

    @WebMethod 
    public void throwsException throws InvalidInputException; 
} 

tôi kết thúc với stacktrace sau khi chạy ứng dụng:

com.sun.xml.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class com.mypackage.ws.services.jaxws.InvalidInputExceptionBean is not found. Have you run APT to generate them? 
    at com.sun.xml.ws.model.RuntimeModeler.getClass(RuntimeModeler.java:285) 
    at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1006) 
    at com.sun.xml.ws.model.RuntimeModeler.processRpcMethod(RuntimeModeler.java:969) 
    at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:546) 
    at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:370) 
    at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:256) 
    at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:322) 
    at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:188) 
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:467) 
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:333) 
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:45) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:121) 

Thêm @XmlRootEntity-InvalidInputException không giải quyết vấn đề.

Nếu đây không phải là cách được khuyến nghị để báo cáo lỗi trên các dịch vụ web, thì có cách nào tốt hơn không? Trường hợp ngoại lệ của tôi có được kế thừa từ RuntimeException và dựa vào phương tiện để xử lý lỗi (tức là, mọi thứ sẽ kết thúc trong một SOAPException)? Tôi đã hy vọng cho một cái gì đó giống như Spring-WS 'SoapFaultAnnotationExceptionResolver. Có cái gì tương tự ở tất cả có sẵn cho JAX-WS?

+0

Có lẽ tôi nên lưu ý rằng lớp mà nó báo cáo là bị thiếu, com.mypackage.ws.services.jaxws.InvalidInputExceptionBean, thực sự không tồn tại. Nhưng tôi cho rằng đó là tự nhiên, rằng nó sẽ được tạo ra như các trạng thái ngoại lệ. – waxwing

Trả lời

25

Bạn đã cố gắng chú thích ngoại lệ của mình với @WebFault? Ngoài ra, bạn có thực hiện getFaultInfo() không?

EDIT: Tôi nhận ra câu trả lời của mình có thể không đủ chi tiết. Như nhắc nhở trong this thread (ví dụ):

2.0 đặc điểm kỹ thuật JAX-WS đòi rằng ngoại trừ chú thích với @WebFault phải có hai cấu trúc và một phương pháp [getter để có được những thông tin lỗi]:

WrapperException(String message, FaultBean faultInfo) 
WrapperException(String message, FaultBean faultInfo, Throwable cause) 
FaultBean getFaultInfo() 

các WrapperException được thay thế bằng tên của ngoại lệ, và FaultBean được thay thế bởi lớp tên mà thực hiện các hạt lỗi. Đậu lỗi là một hạt Java chứa thông tin về lỗi và được sử dụng bởi ứng dụng khách dịch vụ Web để biết nguyên nhân gây ra lỗi.

Chi tiết này được nêu chi tiết trong phần 2.5 Lỗi đặc tả JAX-WS. Ngoại lệ của bạn có phù hợp với điều này không? Bạn có thể gửi mã không?


OP là đúng. Theo đặc điểm kỹ thuật 2.1, mục 3.7 Ngoại lệ cụ thể dịch vụ, không bắt buộc phải sử dụng chú thích @WebFault, JAX-WS có thể tạo các bean bao bọc động cho các ngoại lệ không khớp với mẫu được mô tả trong phần 2.5 (chỉ cung cấp một getter cho thông tin bạn muốn có mặt trong lỗi này). Đối với trường hợp ngoại lệ khớp với mẫu được mô tả trong phần 2.5 (ví dụ: ngoại lệ có phương thức getFaultInfo và chú thích @WebFault), FaultBean được sử dụng làm đầu vào cho JAXB khi ánh xạ ngoại lệ cho Lược đồ XML.

Vì vậy, giải pháp được đề xuất ở trên (khớp với mẫu được mô tả trong phần 2.5) chỉ là giải pháp thay thế. Việc tạo ra các bean wrapper chỉ nên làm việc cho các ngoại lệ khác. Và tôi không biết tại sao điều này lại thất bại ở đây.

+0

Tôi thì không. Tôi đã thử nó ngay bây giờ, nhưng tôi nhận được cùng một lỗi. Nhưng tôi có cần phải chỉ định tên thuộc tính @ WebFault, targetNameSpace và faultBean không? – waxwing

+0

Cảm ơn gợi ý, tôi sẽ xem xét nó. Không, tôi không thực hiện các nhà thầu mà bạn đã chỉ ra. Tôi đọc (misread?) Rằng một phần của đặc tả như việc thực hiện JAX WS sẽ * tự động tạo ra * các wrapper ngoại lệ chính nó với các nhà xây dựng đó. Tôi bắt đầu nghĩ rằng tôi đang làm một cái gì đó ngược lại ... – waxwing

+0

Nó chỉ ra rằng phù hợp với phong cách ngoại lệ bạn đã viết ở trên có nghĩa là JAX-WS sẽ * không * tạo ra một bean wrapper cho trường hợp ngoại lệ, mà nó nếu không nên. Vì vậy, nó hoạt động như một giải pháp cho tôi. Tuy nhiên, nó * nên * làm việc với tất cả các ngoại lệ mà không có chú thích, theo "3.7 Ngoại lệ cụ thể dịch vụ" trong spec. – waxwing

16

Ngoài câu trả lời ở trên. Tôi đã kết thúc với điều này như thực hiện InvalidInputException tôi:

@WebFault(faultBean = "com.mypackage.ws.exception.FaultBean") 
public class InvalidInputException extends Exception { 

    private static final long serialVersionUID = 1L; 

    private FaultBean faultBean; 

    public InvalidInputException() { 
     super(); 
    } 

    public InvalidInputException(String message, FaultBean faultBean, Throwable cause) { 
     super(message, cause); 
     this.faultBean = faultBean; 
    } 

    public InvalidInputException(String message, FaultBean faultBean) { 
     super(message); 
     this.faultBean = faultBean; 
    } 

    public FaultBean getFaultInfo() { 
     return faultBean; 
    } 
} 

FaultBean chỉ là một POJO đơn giản với hiện tại không có dữ liệu nào cả. Bây giờ, theo đặc tả của JAX-WS (xem 3.7 Ngoại lệ cụ thể của dịch vụ), nó tuân theo những gì được yêu cầu của một ngoại lệ được chú thích với @WebFault, vì vậy nó sẽ không tạo ra một bean wrapper cho nó, mà có thể là những gì đã thất bại.

Đây là giải pháp thay thế khá, nhưng không giải thích được lỗi trong câu hỏi.

+1

+1 cho điều này, nó đã lưu ngày của tôi :). Nhưng điều này chỉ làm việc cho các trường hợp ngoại lệ được kiểm tra chứ không phải cho các ngoại lệ không được kiểm soát. Bất kỳ đầu mối ... – mogli

+0

@ waxwing Tôi đã thực hiện một ví dụ tuy nhiên ví dụ của tôi không hoạt động mà không cần xác định phần tử targetNamespace? – kamaci

+0

@rits Cũng đã xảy ra với tôi Tôi đã thử điều này trên Websphere 8.5.5 có Axis 2 là nhà cung cấp dịch vụ cho JAX-WS và nó không hoạt động với RuntimeException, nhưng nó đã làm việc tương tự với Websphere Liberty Profile vì nó sử dụng Apache CXF thay thế. Đó là một sự xấu hổ thực sự bởi vì bây giờ khách hàng của tôi cần phải nắm bắt/tuyên bố ngoại lệ. –

Các vấn đề liên quan