2011-07-12 42 views
12

Sau khi tạo một trình khách dịch vụ web java bằng wsimport trên wsdl, tôi cần đặt tiêu đề Cấp quyền cho mỗi thông báo xà phòng được nhúng trong yêu cầu http. Đã tạo một lớp con của javax.xml.ws.Service, làm thế nào tôi có thể nối thêm một tiêu đề http vào mỗi yêu cầu gửi đi?Máy khách dịch vụ web java, thêm tiêu đề http

+0

[bài viết trên blog này] (http: // vangjee. wordpress.com/2009/02/25/how-to-modify-request-headers-in-a-j2ee-web-application/) cho thấy cách sửa đổi HttpRequestHeaders. Nó giả định rằng bạn đang viết một ứng dụng J2EE. – Davidann

Trả lời

9

Bạn có thể chuyển bản đồ với các tiêu đề tùy chỉnh tới BindingProvider (Tôi tin rằng bạn có thể đặt thuộc tính MessageContext.HTTP_REQUEST_HEADERS). Thử tạo tiêu đề Ủy quyền và chuyển nó vào.

12

Đây là mã, dựa trên câu trả lời của Femi.

Có thể hơi phức tạp để tìm ra. Hoạt động đẹp!

Service jaxwsService = Service.create(wsdlURL, serviceName); 
Dispatch<SOAPMessage> disp = jaxwsService.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE); 

//Add HTTP request Headers 
Map<String, List<String>> requestHeaders = new HashMap<>(); 
requestHeaders.put("Auth-User", Arrays.asList("BILL_GATES")); 
disp.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders); 
+0

Tôi đang gặp một số sự cố với lệnh gọi createDispatch: Công văn disp = jaxwsService.createDispatch (portName, SOAPMessage.class, Service.Mode.THÔNG ĐIỆP); Việc khiếu nại không tìm thấy phương pháp phù hợp. Có điều gì rõ ràng mà tôi đã bỏ lỡ không? Tôi đang nhập nhập javax.xml.soap.SOAPMessage; nhập javax.xml.ws.Dispatch; nhập javax.xml.ws.Service; nhập javax.xml.ws.handler.MessageContext; –

+0

Cảm ơn bạn! Nếu bạn câm như tôi, bạn có thể cố gắng sử dụng một 'Bản đồ ' bởi vì bạn đọc câu trả lời quá nhanh. Đừng như tôi. Sử dụng một 'Bản đồ >' và lưu bốn giờ mà tôi đã cố gắng để sửa lỗi 'Lỗi truyền tải HTTP: java.lang.ClassCastException: java.lang.String không thể được đưa vào java.util.List'. – L42

3

Vì lợi ích của sự hoàn chỉnh và giúp đỡ người khác trong những tình huống tương tự, tôi muốn để minh họa cho giải pháp IMHO sạch bằng cách sử dụng JAX-WS-handler chuỗi:

1) Sub-lớp học của bạn service-class (không phải là port-class) trong một gói khác (không được tạo). Bởi vì lớp dịch vụ (và toàn bộ gói của nó) có thể được tạo ra từ một WSDL, các thay đổi của bạn đối với lớp con sẽ không bị mất, khi bạn cập nhật lớp dịch vụ của bạn sau khi thay đổi WSDL.

2) Chú thích-sub-class dịch vụ của bạn như thế này (nhập khẩu javax.jws.HandlerChain):

@HandlerChain(file="HandlerChain.xml") 
public class MyService extends GeneratedService { 

3) Tạo một tập tin gọi HandlerChain.xml trong gói giống như-sub-class dịch vụ của bạn, tức là bên cạnh MyService với nội dung sau:

<?xml version="1.0" encoding="UTF-8"?> 
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"> 
    <handler-chain> 
     <handler> 
      <handler-name>co.codewizards.example.HttpHeaderExtensionSOAPHandler</handler-name> 
      <handler-class>co.codewizards.example.HttpHeaderExtensionSOAPHandler</handler-class> 
     </handler> 
    </handler-chain> 
</handler-chains> 

Bạn có thể thêm nhiều <handler> phần tử, btw.

Và đảm bảo rằng tệp này thực sự kết thúc trong JAR của bạn! Ví dụ, khi sử dụng Maven, bạn phải đặt nó vào ${project}/src/main/resources/ (thay vì ${project}/src/main/java/) hoặc bạn phải thay đổi cấu hình xây dựng của mình để bao gồm các tài nguyên từ java -folder! Tôi khuyên bạn nên sau này, bởi vì nó cồng kềnh để có một cấu trúc gói song song trong resources -folder, mà thường bị lãng quên trong quá trình tái cấu trúc.

4) Thực hiện của bạn HttpHeaderExtensionSOAPHandler - tương tự như sau:

import static com.google.common.base.Preconditions.*; 

import java.util.*; 

import javax.xml.namespace.QName; 
import javax.xml.ws.handler.MessageContext; 
import javax.xml.ws.handler.soap.SOAPHandler; 
import javax.xml.ws.handler.soap.SOAPMessageContext; 

import co.codewizards.webservice.WebserviceContext; 

public class HttpHeaderExtensionSOAPHandler implements SOAPHandler<SOAPMessageContext> { 

    @Override 
    public boolean handleMessage(SOAPMessageContext context) { 
     checkNotNull(context, "context"); 

     Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 
     checkNotNull(outboundProperty, "outboundProperty"); 

     if (outboundProperty.booleanValue()) { 
      WebserviceContext<?, ?> webserviceContext = WebserviceContext.getThreadWebserviceContextOrFail(); 
      String something = (String) webserviceContext.___(); // my API method ;-) 

      @SuppressWarnings("unchecked") 
      Map<String, List<String>> requestHeaders = (Map<String, List<String>>) context.get(MessageContext.HTTP_REQUEST_HEADERS); 
      if (requestHeaders == null) { 
       requestHeaders = new HashMap<String, List<String>>(); 
       context.put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders); 
      } 
      requestHeaders.put(MyService.MY_CONSTANT, Collections.singletonList(something)); 
     } 
     return true; 
    } 

    @Override 
    public boolean handleFault(SOAPMessageContext context) { return true; } 

    @Override 
    public void close(MessageContext context) { } 

    @Override 
    public Set<QName> getHeaders() { return Collections.emptySet(); } 
} 

Trong ví dụ của tôi ở trên (và trong mã hiệu của tôi) tôi có được các dữ liệu được chuyển vào các tiêu đề yêu cầu HTTP từ một ThreadLocale, tức là ngữ cảnh của luồng hiện tại của tôi. Vì đây là lớp tùy chỉnh của tôi, bạn cần phải triển khai theo cách riêng của mình để truy cập dữ liệu của mình.

1

khi bạn đang gửi ở chế độ tin nhắn, bạn cũng có thể vượt qua MimeHeaders trên tin nhắn SOAP, mà cuối cùng sẽ chuyển thành tiêu đề http, ví dụ:

soapMessage.getMimeHeaders().addHeader("Authorization","Basic [md5]") 
Các vấn đề liên quan