我编写了以下代码来实现一个Java Web服务,该服务与同一主机上用另一种语言编写的应用程序进行通信:
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService(name = "MyWebService")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
public class MyWebService {
@WebMethod(operationName = "methodName", action = "urn:#methodName")
@WebResult(name = "result", partName = "output")
public String methodName(@WebParam(name = "param1", partName = "input") String param1,
@WebParam(name = "param2", partName = "input") String param2){
// ...do something
return "You called this service with params: " + param1 + "," + param2;
}
由于要求不是使用应用程序服务器来公开 Web 服务,因此我从另一个类实例化了该服务,如下所示:
Endpoint endpoint = Endpoint.create(new MyWebService());
URL url = new URL("http://localhost:7777/MyWebService");
endpoint.publish(url.toString());
问题:
1(考虑到该项目的架构,使用用户名和密码保护此服务的最简单方法是什么?任何代码示例将不胜感激。
2(我做了一些研究,发现了SOAPHandler的使用,我认为它对我有用。在使用 SOAPHandler 类的情况下,如何向消息添加标头以要求客户端进行身份验证?
提前谢谢你
非常感谢您的回复,这也是我遵循的方向,但是
例如,当我检查任何标题时:
SOAPHeader header = soapContext.getMessage().getSOAPPart().getEnvelope().getHeader();
Iterator<SOAPElement> iterator = header.getAllAttributes();
我收到空指针异常...有什么想法吗?
我做了一个工作程序。只是为了补充你已经发现的内容,以下是使用处理程序的一种方法
Endpoint endpoint = Endpoint.create(new MyWebService());
Binding binding = endpoint.getBinding();
List<Handler> handlerChain = new ArrayList<Handler>(1);
handlerChain.add(new MyHandler());
binding.setHandlerChain(handlerChain);
URL url = new URL("http://localhost:7777/MyWebService");
endpoint.publish(url.toString());
MyHandler
是类扩展Handler
接口。 或者,您可以使用@HandlerChain
注释,这将需要处理程序的 xml 配置文件。仅为传入邮件配置此项
public class MyHandler implements SOAPHandler{
@Override
public Set<?> getHeaders() {
// TODO Auto-generated method stub
return null;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public boolean handleFault(MessageContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean handleMessage(MessageContext context) {
System.out.println("Hehehe the handler");
SOAPMessageContext soapContext = (SOAPMessageContext)context;
try {
SOAPHeader header = soapContext.getMessage().getSOAPPart().getEnvelope().getHeader();
//Check there if the required data (username/password) is present in header or not and return true/false accordingly.
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
}
同样从客户端来看,如果您的客户端使用的是 JAB-WS,则必须使用客户端处理程序。下面是一个典型的 JAX-WS 客户机调用示例
Dispatch<Source> dispatch = … create a Dispatch<Source>
dispatch.getBinding().setHandlerChain(chain)
Source request = … create a Source object
Source response = dispatch.invoke(request);
在这里,链中的处理程序将向传出请求添加标头。仅为传出邮件配置此项。
你所做的是公平的。
关于身份验证,您可以公开一种将用户名和密码作为登录凭据传递的方法。
用户提供正确的凭据后,用户已经过身份验证。
注意:现在,您必须维护会话数据,并确保传入请求来自经过身份验证的用户。该Endpoint
只是在内部部署一个轻量级的 http 服务器。您必须设计 Web 服务实现以在请求之间保持"状态"。
您还有 2 个选择。
- 在 SOAP 级别执行身份验证。我真的不推荐它。但是,如果这样做,请注意,
Endpoint
不会部署WSDL
. 因此,您必须与连接的客户端进行精确通信,所需的SOAP
标头。虽然可以写一个WSDL
自己并将其"附加"到Endpoint
. - 在 http 请求级别执行身份验证。 即添加令牌或cookie 到 http 请求。老实说,我不记得这是否使用
Endpoint
很容易