Java JSF中的JAX-WS调用

Java JSF中的JAX-WS调用,java,web-services,jsf,jsf-2,wsdl,Java,Web Services,Jsf,Jsf 2,Wsdl,我已经使用wsimport将WSDL文件转换为java <h:body> <h3>Calculator</h3> <h:form> <h:inputText value="#{?}"></h:inputText> //for @para1 <h:inputText value="#{?}"></h:inputText> //for @para2 <h:inputText

我已经使用wsimport将WSDL文件转换为java

<h:body>
<h3>Calculator</h3>
<h:form>
    <h:inputText value="#{?}"></h:inputText> //for @para1
    <h:inputText value="#{?}"></h:inputText> //for @para2
    <h:inputText value="#{?}"></h:inputText> //for @para3
    <h:commandButton value="Calculate" action="?"></h:commandButton>
</h:form>
<h:panelGroup">
<h4>Results</h4>
<table>
  <tr><td>${?}</td></tr>
</table>
</h:panelGroup>
</h:body>
它生成两个文件

ICalculator

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Action;


@WebService(name = "ICalculator", targetNamespace = "http://ws.test.ews/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface ICalculator {


/**
 * 
 * @param arg2
 * @param arg1
 * @param arg0
 * @return
 *     returns int
 */
@WebMethod(operationName = "PerformCalculation")
@WebResult(partName = "return")
@Action(input = "http://ws.test.ews/ICalculator/PerformCalculationRequest", output = "http://ws.test.ews/ICalculator/PerformCalculationResponse")
public int performCalculation(
    @WebParam(name = "arg0", partName = "arg0")
    int arg0,
    @WebParam(name = "arg1", partName = "arg1")
    int arg1,
    @WebParam(name = "arg2", partName = "arg2")
    String arg2);

}
计算器mplservice

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;



@WebServiceClient(name = "CalculatorImplService", targetNamespace = "http://ws.test.ews/", wsdlLocation = "http://localhost:9998/ws/calculator?wsdl")
public class CalculatorImplService
extends Service
{

private final static URL CALCULATORIMPLSERVICE_WSDL_LOCATION;
private final static WebServiceException CALCULATORIMPLSERVICE_EXCEPTION;
private final static QName CALCULATORIMPLSERVICE_QNAME = new QName("http://ws.test.ews/", "CalculatorImplService");

static {
    URL url = null;
    WebServiceException e = null;
    try {
        url = new URL("http://localhost:9998/ws/calculator?wsdl");
    } catch (MalformedURLException ex) {
        e = new WebServiceException(ex);
    }
    CALCULATORIMPLSERVICE_WSDL_LOCATION = url;
    CALCULATORIMPLSERVICE_EXCEPTION = e;
}

public CalculatorImplService() {
    super(__getWsdlLocation(), CALCULATORIMPLSERVICE_QNAME);
}

public CalculatorImplService(WebServiceFeature... features) {
    super(__getWsdlLocation(), CALCULATORIMPLSERVICE_QNAME, features);
}

public CalculatorImplService(URL wsdlLocation) {
    super(wsdlLocation, CALCULATORIMPLSERVICE_QNAME);
}

public CalculatorImplService(URL wsdlLocation, WebServiceFeature... features) {
    super(wsdlLocation, CALCULATORIMPLSERVICE_QNAME, features);
}

public CalculatorImplService(URL wsdlLocation, QName serviceName) {
    super(wsdlLocation, serviceName);
}

public CalculatorImplService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
    super(wsdlLocation, serviceName, features);
}

/**
 * 
 * @return
 *     returns ICalculator
 */
@WebEndpoint(name = "CalculatorImplPort")
public ICalculator getCalculatorImplPort() {
    return super.getPort(new QName("http://ws.test.ews/", "CalculatorImplPort"), ICalculator.class);
}

/**
 * 
 * @param features
 *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
 * @return
 *     returns ICalculator
 */
@WebEndpoint(name = "CalculatorImplPort")
public ICalculator getCalculatorImplPort(WebServiceFeature... features) {
    return super.getPort(new QName("http://ws.test.ews/", "CalculatorImplPort"), ICalculator.class, features);
}

private static URL __getWsdlLocation() {
    if (CALCULATORIMPLSERVICE_EXCEPTION!= null) {
        throw CALCULATORIMPLSERVICE_EXCEPTION;
    }
    return CALCULATORIMPLSERVICE_WSDL_LOCATION;
}

}
现在我想在JSF中调用这个WEB服务。页面(JSF)发送三个参数并获得结果

JSF页面

<h:body>
<h3>Calculator</h3>
<h:form>
    <h:inputText value="#{?}"></h:inputText> //for @para1
    <h:inputText value="#{?}"></h:inputText> //for @para2
    <h:inputText value="#{?}"></h:inputText> //for @para3
    <h:commandButton value="Calculate" action="?"></h:commandButton>
</h:form>
<h:panelGroup">
<h4>Results</h4>
<table>
  <tr><td>${?}</td></tr>
</table>
</h:panelGroup>
</h:body>

计算器
//对于@para1
//对于@para2
//对于@para3

使用
@webservicef
注释引用托管bean中的webservice存根类(
CalculatorImplService
)。使用
MyManagedBean
的托管bean类,您的代码可能是什么样子的一个粗略示例如下:

@Named("myBean")
@RequestScoped
public class MyManagedBean{

@WebServiceRef(wsdlLocation="http://localhost:9998/ws/calculator?wsdl",value=CalculatorImplService.class)   
 ICalculator calculatorService;


 public void calculate(int arg1,int arg2){
    calculatorService.calculate();
 }

}

在这里,我使用了CDI
@命名的
注释。如果愿意,您可以自由使用
@ManagedBean

谢谢kolossus。如果webservice位于另一个项目(和另一台服务器)中,那么将wsdllocation硬编码到任何地方似乎都是不灵活的,例如在测试方面。你有办法避免硬编码吗?;-)我认为可注入的应用程序范围bean是端口的“工厂”,不会有任何硬编码(它有一个所有不同WebServiceClient的实例,以及获取端口实例的方法)。如果你有其他想法,我可以提出一个新问题:-)这是一个可行的选择@JaqenH'ghar。可以将WSDL位置加载为JNDI属性的生产者方法也应该可以工作(如果我们可以使用基本的
@webservicef
wsdlLocation
变量提供EL属性或JNDI属性,这将更为理想-还没有研究规范是否支持这一点)感谢kolossus,我现在已经创建了一个EJB层(用于获取池),每个实例都有一个使用新CalculatorImplService()检索的端口。getCalculatorImplPort()。它似乎工作得很好。感谢您的投入:-)