Java 验证Spring SOAP到Workday
我对处理SOAP请求非常陌生,我正在尝试使用Workday列出的SOAP api。我使用了Java 验证Spring SOAP到Workday,java,spring,soap,wsdl,workday-api,Java,Spring,Soap,Wsdl,Workday Api,我对处理SOAP请求非常陌生,我正在尝试使用Workday列出的SOAP api。我使用了gradle/ant脚本根据Spring教程从WSDL生成类 现在类已经生成,我可以访问我需要的函数了。问题是我不知道如何验证我的请求 这就是我到目前为止所做的: import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.ws.client.core.support.WebServiceGatewaySup
gradle/ant
脚本根据Spring教程从WSDL生成类
现在类已经生成,我可以访问我需要的函数了。问题是我不知道如何验证我的请求
这就是我到目前为止所做的:
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import workday_Staffing.wsdl.GetWorkersRequestType;
import workday_Staffing.wsdl.GetWorkersResponseType;
public class StaffingClient extends WebServiceGatewaySupport {
public StaffingClient() {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath("workday_Staffing.wsdl");
setMarshaller(jaxb2Marshaller);
setUnmarshaller(jaxb2Marshaller);
}
public void makeWorkdayRequest() {
// make the request - missing some authentication here
GetWorkersRequestType request = new GetWorkersRequestType();
GetWorkersResponseType workersResponseType = (GetWorkersResponseType) getWebServiceTemplate()
.marshalSendAndReceive(request);
}
}
答案似乎是一个很好的线索,但我不知道如何构建客户端和添加身份验证
任何帮助都将不胜感激。主要是,通过WS-Security凭据的SOAPHandler,您似乎缺少了身份验证部分。仅供参考,这不是Spring,而是API第16版的代码 谢谢你的记忆之旅 台阶
- 找工人
- 工作日凭证
package com.workday.demo;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Map;
import java.math.BigDecimal;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.BindingProvider;
import com.workday.human_resources.*;
public class GetWorkers {
public static void main(String[] args) {
try {
// Enter user/password and endpoint information for Proof of Concept
final String wdUser = "user@tenant";
final String wdPassword = "zzz";
// final String wdEndpoint =
// "https://e2-impl-cci.workday.com/ccx/service/exampleTenant/Human_Resources/v16";
final String wdEndpoint = "https://impl-cc.workday.com/ccx/service/exampleTenant/Human_Resources/v16";
System.out.println("Starting...");
// Create the Web Service client stub
HumanResourcesService service = new HumanResourcesService();
HumanResourcesPort port = service.getHumanResources();
// Add the WorkdayCredentials handler to the client stub
WorkdayCredentials.addWorkdayCredentials((BindingProvider) port, wdUser, wdPassword);
// Assign the Endpoint URL
Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wdEndpoint);
// Define the paging defaults
final int countSize = 200;
int totalPages = 1;
int currentPage = 1;
// Set the current date/time
GregorianCalendar cal = new GregorianCalendar();
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
// Loop over all of the pages in the web service response
while (totalPages >= currentPage) {
// Create a "request" object
GetWorkersRequestType request = new GetWorkersRequestType();
// Set the WWS version desired
request.setVersion("v10");
// Set the date/time & page parameters in the request
ResponseFilterType responseFilter = new ResponseFilterType();
responseFilter.setAsOfEntryDateTime(xmlCal);
responseFilter.setAsOfEffectiveDate(xmlCal);
responseFilter.setPage(BigDecimal.valueOf(currentPage));
responseFilter.setCount(BigDecimal.valueOf(countSize));
request.setResponseFilter(responseFilter);
// Set the desired response group(s) to return
WorkerResponseGroupType responseGroup = new WorkerResponseGroupType();
responseGroup.setIncludeReference(true);
request.setResponseGroup(responseGroup);
// Submit the request creating the "response" object
GetWorkersResponseType response = port.getWorkers(request);
// Display all Workers
Iterator<WorkerType> i = response.getResponseData().getWorker()
.iterator();
while (i.hasNext()) {
WorkerType worker = i.next();
{
System.out.println(worker.getWorkerReference()
.getDescriptor());
}
}
// Update page number
if (totalPages == 1) {
totalPages = response.getResponseResults().getTotalPages()
.intValue();
}
currentPage++;
}
} catch (ProcessingFaultMsg e) {
e.printStackTrace();
} catch (ValidationFaultMsg e) {
e.printStackTrace();
} catch (DatatypeConfigurationException e) {
e.printStackTrace();
}
}
}
package com.workday.demo;
导入java.util.GregorianCalendar;
导入java.util.Iterator;
导入java.util.Map;
导入java.math.BigDecimal;
导入javax.xml.datatype.DatatypeConfigurationException;
导入javax.xml.datatype.DatatypeFactory;
导入javax.xml.datatype.XMLGregorianCalendar;
导入javax.xml.ws.BindingProvider;
导入com.workday.human_resources.*;
公营部门员工{
公共静态void main(字符串[]args){
试一试{
//输入用户/密码和端点信息以进行概念验证
最终字符串wdUser=”user@tenant";
最终字符串wdPassword=“zzz”;
//最终字符串端点=
// "https://e2-impl-cci.workday.com/ccx/service/exampleTenant/Human_Resources/v16";
最终字符串wdEndpoint=”https://impl-cc.workday.com/ccx/service/exampleTenant/Human_Resources/v16";
System.out.println(“开始…”);
//创建Web服务客户端存根
HumanResourcesService=新的HumanResourcesService();
HumanResourcesSport端口=service.getHumanResources();
//将WorkdayCredentials处理程序添加到客户端存根
WorkdayCredentials.addWorkdayCredentials((BindingProvider)端口、wdUser、wdPassword);
//分配端点URL
Map requestContext=((BindingProvider)端口).getRequestContext();
put(BindingProvider.ENDPOINT\u ADDRESS\u属性,wdEndpoint);
//定义分页默认值
最终整数countSize=200;
int totalPages=1;
int currentPage=1;
//设置当前日期/时间
GregorianCalendar cal=新的GregorianCalendar();
XMLGregorianCalendar xmlCal=DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
//在web服务响应中的所有页面上循环
while(totalPages>=currentPage){
//创建一个“请求”对象
GetWorkersRequestType请求=新建GetWorkersRequestType();
//设置所需的WWS版本
请求设置版本(“v10”);
//在请求中设置日期/时间和页面参数
ResponseFilterType responseFilter=新的ResponseFilterType();
responseFilter.setAsOfEntryDateTime(xmlCal);
responseFilter.SetaSofectiveDate(xmlCal);
responseFilter.setPage(BigDecimal.valueOf(currentPage));
responseFilter.setCount(BigDecimal.valueOf(countSize));
request.setResponseFilter(responseFilter);
//将所需的响应组设置为返回
WorkerResponseGroupType responseGroup=新的WorkerResponseGroupType();
responseGroup.setIncludeReference(真);
request.setResponseGroup(responseGroup);
//提交创建“响应”对象的请求
GetWorkersResponseType response=port.getWorkers(请求);
//显示所有工作人员
迭代器i=response.getResponseData().getWorker()
.iterator();
while(i.hasNext()){
WorkerType worker=i.next();
{
System.out.println(worker.getWorkerReference()
.getDescriptor());
}
}
//更新页码
如果(总页数==1){
totalPages=response.getResponseResults().getTotalPages()
.intValue();
}
currentPage++;
}
}捕获(处理错误消息e){
e、 printStackTrace();
}捕获(ValidationFaultMsg e){
e、 printStackTrace();
}捕获(DatatypeConfigurationException e){
e、 printStackTrace();
}
}
}
Workday凭证代码
package com.workday.demo;
import java.util.List;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.namespace.QName;
import java.util.Set;
/**
* This class creates a handler that will add the WS-Security username and
* password to the to the SOAP request messages for a client side proxy.
*
*/
public class WorkdayCredentials implements SOAPHandler<SOAPMessageContext> {
/** Namespace for the SOAP Envelope. */
private static String SOAPENVNamespace = "http://schemas.xmlsoap.org/soap/envelope/";
/** The prefix that will be used for the SOAP Envelope namespace. */
private static String SOAPENVPrefix = "soapenv";
/** Namespace for the WS-Security SOAP header elements. */
private static String WSSENamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
/** The prefix that will be used for the WS-Security namespace. */
private static String WSSEPrefix = "wsse";
/**
* The WS-Security URI that specifies that the password will be transmitted
* as plain text.
*/
private static String WSSEPasswordText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
/**
* The user name that will be sent in the WS-Security header on the SOAP
* request message. This is of the form systemid@tenant.
*/
private String username;
/**
* The password that will be sent in the WS-Security header on the SOAP
* request message.
*/
private String password;
/**
* This method created an instance of the WorkdayCredentials class and adds
* it as a handler to the bindingProvider supplied.
*
* @param bindingProvider
* The client stub to which the handler will be added. The most
* convenient way to obtain the required bindingProvvider is to
* call one of the getPort methods on the Service class for the
* Web service and then cast the returned object to a
* BindingProvider.
* @param username
* The id and tenant name for the user. This is of the form
* systemid@tenant.
* @param password
* The password for the system user.
*/
@SuppressWarnings("unchecked")
public static void addWorkdayCredentials(BindingProvider bindingProvider,
String username, String password) {
List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
handlerChain.add(new WorkdayCredentials(username, password));
bindingProvider.getBinding().setHandlerChain(handlerChain);
}
/**
* Creates a WorkdayCredentials handler and initialises the member
* variables. In most cases, the addWorkdayCredentials static method should
* be used instead.
*
* @param username
* The id and tenant name for the user. This is of the form
* systemid@tenant.
* @param password
* The password for the system user.
*/
public WorkdayCredentials(String username, String password) {
this.username = username;
this.password = password;
}
/**
* Returns null as this handler doesn't process any Headers, it just adds
* one.
*/
public Set<QName> getHeaders() {
return null;
}
/**
* Adds WS-Security header to request messages.
*/
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
addWSSecurityHeader(smc, username, password);
}
return true;
}
/**
* Returns true, no action is taken for faults messages.
*/
public boolean handleFault(SOAPMessageContext smc) {
return true;
}
public void close(MessageContext messageContext) {
}
/**
* Adds a WS-Security header containing a UsernameToken to a SOAP message.
*
* @param smc
* The SOAPMessageContent to which the WS-Security header will be
* added.
* @param username
* The WS-Security username.
* @param password
* The WS-Security password.
*
* @throws java.lang.RuntimeException
* This exception will be thrown if a SOAPException occurs when
* modifying the message.
*/
private void addWSSecurityHeader(SOAPMessageContext smc, String username,
String password) throws java.lang.RuntimeException {
try {
// Get the SOAP Header
SOAPMessage message = smc.getMessage();
SOAPHeader header = message.getSOAPHeader();
if (header == null) {
// Create header as it doesn't already exist
message.getSOAPPart().getEnvelope().addHeader();
header = message.getSOAPHeader();
}
// Add WS-Security SOAP Header
SOAPElement heSecurity = header.addChildElement("Security",
WSSEPrefix, WSSENamespace);
heSecurity.addAttribute(message.getSOAPPart().getEnvelope()
.createName("mustUnderstand", SOAPENVPrefix,
SOAPENVNamespace), "1");
// Add the Usernametoken element to the WS-Security Header
SOAPElement heUsernameToken = heSecurity.addChildElement(
"UsernameToken", WSSEPrefix, WSSENamespace);
// Add the Username element to the UsernameToken Element
heUsernameToken.addChildElement("Username", WSSEPrefix,
WSSENamespace).addTextNode(username);
// Add the Password element to the UsernameToken Element
SOAPElement hePassword = heUsernameToken.addChildElement(
"Password", WSSEPrefix, WSSENamespace);
hePassword.addAttribute(message.getSOAPPart().getEnvelope()
.createName("Type"), WSSEPasswordText);
hePassword.addTextNode(password);
} catch (SOAPException e) {
throw new RuntimeException(
"Failed to add WS-Security header to request", e);
}
}
}
package com.workday.demo;
导入java.util.List;
导入javax.xml.soap.SOAPElement;
导入javax.xml.soap.SOAPException;
导入javax.xml.soap.SOAPHeader;
导入javax.xml.soap.SOAPMessage;
导入javax.xml.ws.BindingProvider;
导入javax.xml.ws.handler.handler;
导入javax.xml.ws.handler.MessageContext;
导入javax.xml.ws.handler.soap.SOAPHandler;
导入javax.xml.ws.handler.soap.SOAPMessageContext;
导入javax.xml.namespace.QName;
进口ja