如何为JAX-WS Service类的URL连接添加Auth头解决401错误?
JAX-WS Service构造时WSDL加载401授权问题的解决办法
方案1:自定义URLStreamHandler添加认证头
通过自定义URLStreamHandler,在构造Service使用的URL时注入认证逻辑,让加载WSDL的请求自动携带Authorization头。
实现自定义Handler:
import java.io.IOException; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; import java.util.Base64; public class AuthenticatedURLHandler extends URLStreamHandler { private final String username; private final String password; public AuthenticatedURLHandler(String username, String password) { this.username = username; this.password = password; } @Override protected URLConnection openConnection(URL url) throws IOException { URLConnection connection = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile()).openConnection(); String authCredentials = username + ":" + password; String encodedAuth = Base64.getEncoder().encodeToString(authCredentials.getBytes()); connection.setRequestProperty("Authorization", "Basic " + encodedAuth); return connection; } }
使用该Handler构造Service:
String wsdlUrl = "https://your-service-url?wsdl"; String authUser = "your-username"; String authPass = "your-password"; URL authenticatedWsdlUrl = new URL(null, wsdlUrl, new AuthenticatedURLHandler(authUser, authPass)); service = new ClassThatExtendsService(authenticatedWsdlUrl);
方案2:使用本地WSDL文件
提前将WSDL下载到本地项目中,构造Service时加载本地文件,避免构造阶段发起远程请求,之后再通过BindingProvider设置服务调用的认证信息。
// 加载本地WSDL文件(假设放在src/main/resources/wsdl目录下) URL localWsdlUrl = getClass().getResource("/wsdl/your-service.wsdl"); service = new ClassThatExtendsService(localWsdlUrl); // 获取服务端口并设置认证 YourServicePort port = service.getYourServicePort(); BindingProvider bindingProvider = (BindingProvider) port; // 设置远程服务地址 bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://your-service-url"); // 设置Basic认证参数 bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "your-username"); bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "your-password");
方案3:通过wsimport打包WSDL到应用
使用wsimport生成Service代码时,指定-wsdlLocation参数将WSDL打包到应用资源中,构造Service时默认加载本地WSDL,调用时再指向远程服务并配置认证。
生成代码的命令示例:
wsimport -keep -wsdlLocation /wsdl/your-service.wsdl https://your-service-url?wsdl
调用代码:
service = new ClassThatExtendsService(); YourServicePort port = service.getYourServicePort(); BindingProvider bindingProvider = (BindingProvider) port; // 指向远程服务地址 bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://your-service-url"); // 设置认证信息 bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "your-username"); bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "your-password");
内容的提问来源于stack exchange,提问作者Ethan Solomon
相关产品推荐
相关产品推荐

