Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to talk about Spring2.5 Collection Web Service

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

How to talk about Spring2.5 collection Web Service, I believe that many inexperienced people are at a loss about this. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.

Exposing servlet-based web services using JAX-RPC

Spring provides a convenient base class for the endpoint implementation of JAX-RPC servlet-ServletEndpointSupport. To expose our AccountService in the future, we extend Spring's ServletEndpointSupport class and implement our business logic here, usually handing over the call to the business layer.

/ * * JAX-RPC compliant RemoteAccountService implementation that simply delegates * to the AccountService implementation in the root web application context. * This wrapper class is necessary because JAX-RPC requires working with dedicated * endpoint classes. If an existing service needs to be exported, a wrapper that * extends ServletEndpointSupport for simple application context access is * the simplest JAX-RPC compliant way. * * This is the class registered with the server-side JAX-RPC implementation. * In the case of Axis, this happens in "server-config.wsdd" respectively via * deployment calls. The web service engine manages the lifecycle of instances * of this class: A Spring application context can just be accessed here. * / import org.springframework.remoting.jaxrpc.ServletEndpointSupport; public class AccountServiceEndpoint extends ServletEndpointSupport implements RemoteAccountService {private AccountService biz; protected void onInit () {this.biz = (AccountService) getWebApplicationContext (). GetBean ("accountService");} public void insertAccount (Account acc) throws RemoteException {biz.insertAccount (acc);} public Account [] getAccounts (String name) throws RemoteException {return biz.getAccounts (name);}}

AccountServletEndpoint needs to be run in a web application in the same context in Spring to gain access to Spring. If you use Axis, copy the AxisServlet definition to your 'web.xml'' and set the endpoint in 'server-config.wsdd' (or use the publishing tool). See how OrderService is published as a Web service using Axis in the example of JPetStore.

Use JAX-RPC to access web services

Spring provides two factories bean for creating Web service proxies, LocalJaxRpcServiceFactoryBean and JaxRpcPortProxyFactoryBean. The former returns only one JAX-RPC service class for us to use. The latter is a full-featured version that returns a proxy that implements our business service interface. In this example, we use the latter to create a proxy for the AccountService endpoint exposed in the previous paragraph. You'll see that Spring provides excellent support for Web services, requiring very little code-mostly through an Spring configuration file similar to the following:

ServiceInterface is the remote business interface that our clients will use. WsdlDocumentUrl is the URL of WSDL file. Spring needs it as a starting point to create JAX-RPC services. NamespaceUri corresponds to the targetNamespace in the .wsdl file. ServiceName corresponds to the service name in the .wsdl file. PortName corresponds to the port number in the .wsdl file.

Now we can easily access the web service because we have a bean factory that can expose it as a RemoteAccountService interface. We can use this in Spring:

...

From the point of view of the client code, in addition to throwing RemoteException, we can access the web service as a normal class.

Public class AccountClientImpl {private RemoteAccountService service; public void setService (RemoteAccountService service) {this.service = service;} public void foo () {try {service.insertAccount (...);} catch (RemoteException ex) {/ / ouch}

We can not check for a controlled exception RemoteException because Spring automatically converts it to the corresponding unmanaged exception RemoteException. This also requires us to provide a non-RMI interface. The configuration file is now as follows:

Our serviceInterface has become a non-RMI interface. Our RMI interface is now defined using the portInterface attribute. Our client code avoids handling exception java.rmi.RemoteException:

Public class AccountClientImpl {private AccountService service; public void setService (AccountService service) {this.service = service;} public void foo () {service.insertAccount (...);}}

Note that you can also remove the "portInterface" section and specify a normal business interface as "serviceInterface". In this way, JaxRpcPortProxyFactoryBean will automatically switch to the JAX-RPC "dynamic invocation interface" without using a fixed port stub for dynamic invocation. The advantage of this is that you don't even need to use a RMI-related Java interface (for example, in a non-Java target web service); you just need a matching business interface. Check out JaxRpcPortProxyFactoryBean's javadoc for details of the runtime implementation.

Register JAX-RPC Bean Mappin

In order to pass complex objects like Account, we must register the bean mapping on the client side.

Be careful

On the server side, Axis is usually used for bean mapping registration in 'server-config.wsdd'.

We will use Axis to register the bean mapping on the client side. To do this, we need to register the bean map programmatically:

Public class AxisPortProxyFactoryBean extends JaxRpcPortProxyFactoryBean {protected void postProcessJaxRpcService (Service service) {TypeMappingRegistry registry = service.getTypeMappingRegistry (); TypeMapping mapping = registry.createTypeMapping (); registerBeanMapping (mapping, Account.class, "Account"); registry.register ("http://schemas.xmlsoap.org/soap/encoding/", mapping) } protected void registerBeanMapping (TypeMapping mapping, Class type, String name) {QName qName = new QName ("http://localhost:8080/account/services/accountService", name); mapping.register (type, qName, new BeanSerializerFactory (type, qName), new BeanDeserializerFactory (type, qName);}}

Register your own JAX-RPC processor

In this section, we will register our own javax.rpc.xml.handler.Handler to the Web service proxy so that we can execute custom code before the SOAP message is sent. Handler is a callback interface. There is a convenient base class javax.rpc.xml.handler.GenericHandler in jaxrpc.jar for us to inherit:

Public class AccountHandler extends GenericHandler {public QName [] getHeaders () {return null;} public boolean handleRequest (MessageContext context) {SOAPMessageContext smc = (SOAPMessageContext) context; SOAPMessage msg = smc.getMessage (); try {SOAPEnvelope envelope = msg.getSOAPPart () .getEnvelope (); SOAPHeader header = envelope.getHeader () ...} catch (SOAPException ex) {throw new JAXRPCException (ex);} return true;}}

All we need to do now is register AccountHandler with the JAX-RPC service so that it can call handleRequest (..) before the message is sent. Spring currently does not provide declarative support for registration processing, so we have to use it programmatically. But this is easy to achieve in Spring, we just need to overwrite postProcessJaxRpcService (..), which is specially designed for this purpose. Methods:

Public class AccountHandlerJaxRpcPortProxyFactoryBean extends JaxRpcPortProxyFactoryBean {protected void postProcessJaxRpcService (Service service) {QName port = new QName (this.getNamespaceUri (), this.getPortName ()); List list = service.getHandlerRegistry (). GetHandlerChain (port); list.add (new HandlerInfo (AccountHandler.class, null, null)); logger.info ("Registered JAX-RPC AccountHandler on port" + port);}}

* We should remember to change the Spring configuration file to use our factory bean:

...

Exposing servlet-based web services using JAX-WS

Spring provides a convenient base class for JAX-WS servlet endpoint implementation-SpringBeanAutowiringSupport. To expose our AccountService interface, we can extend Spring's SpringBeanAutowiringSupport class and implement our business logic, usually handing the call to the business layer. We will simply use the @ Autowired annotation of Spring 2.5 to declare bean that relies on Spring management.

/ * * JAX-WS compliant AccountService implementation that simply delegates * to the AccountService implementation in the root web application context. * This wrapper class is necessary because JAX-WS requires working with dedicated * endpoint classes. If an existing service needs to be exported, a wrapper that * extends SpringBeanAutowiringSupport for simple Spring bean autowiring (through * the @ Autowired annotation) is the simplest JAX-WS compliant way. * * This is the class registered with the server-side JAX-WS implementation. * In the case of a Java EE 5 server, this would simply be defined as a servlet * in web.xml, with the server detecting that this is a JAX-WS endpoint and reacting * accordingly. The servlet name usually needs to match the specified WS service name. * * The web service engine manages the lifecycle of instances of this class. * Spring bean references will just be wired in here. * / import org.springframework.web.context.support.SpringBeanAutowiringSupport; @ WebService (serviceName= "AccountService") public class AccountServiceEndpoint extends SpringBeanAutowiringSupport {@ Autowired private AccountService biz; @ WebMethod public void insertAccount (Account acc) {biz.insertAccount (acc);} @ WebMethod public Account [] getAccounts (String name) {return biz.getAccounts (name);}}

In order for the Spring facility to be used in the Spring context, our AccountServletEndpoint class needs to run in the same web application. This is the default in the Java EE 5 environment, which installs the standard contract using JAX-WS servlet endpoints. See the Java EE 5 web Services tutorial for more information.

Expose individual web services using JAX-WS

The built-in JAX-WS provider provided by Sun JDK 1.6 uses a built-in HTTP server to expose web services. Spring's SimpleJaxWsServiceExporter class detects all l@WebService annotated bean configured in the Spring application context, and then exposes them through the default JAX-WS server (JDK 1.6 HTTP server).

In this scenario, the endpoint instance is defined and managed as a Spring bean. They will be registered with JAX-WS, but their life cycle will always follow the Spring application context. This means that Spring's display dependency injection can be used for endpoint instances. Of course, annotation-driven injection through @ Autowired also works.

......

The AccountServiceEndpoint class may or may not be derived from Spring's SpringBeanAutowiringSupport class. Because the endpoint here is bean, which is fully managed by Spring. This means that the endpoint implementation may not have any parent class definition as follows-and the @ Autowired configuration annotation for Spring can still be used:

WebService (serviceName= "AccountService") public class AccountServiceEndpoint {@ Autowired private AccountService biz; @ WebMethod public void insertAccount (Account acc) {biz.insertAccount (acc);} @ WebMethod public Account [] getAccounts (String name) {return biz.getAccounts (name);}}

Expose services using JAX-WS RI supported by Spring

Sun's JAX-WS RI was developed as part of the GlassFish project, using Spring support as part of the JAX-WS Commons project. This allows JAX-WS endpoints to be defined as bean managed by Spring. This is similar to the separate pattern discussed in the previous section-but this time in a Servlet environment. Note that this is not portable in Java EE 5 environments, and it is recommended that you embed JAX-WS RI in web application environments without EE, such as Tomcat.

Unlike the standard way of exposing servlet-based endpoints, the life cycle of the endpoint instance will be managed by Spring. Here there will be only one JAX-WS servlet definition in web.xml. In the standard Java EE 5 style (shown above), you would define a servlet for each service endpoint, each of which is proxied to Spring bean (by using @ Autowired, as shown above).

For details on installation and use, please refer to https://jax-ws-commons.dev.java.net/spring/.

Use JAX-WS to access web services

Similar to JAX-RPC support, Spring provides two factory bean to create JAX-WS web service proxies, which are LocalJaxWsServiceFactoryBean and JaxWsPortProxyFactoryBean. The previous one can only return one JAX-WS service object for us to use. What follows is the full version of the proxy implementation that can return to our business service interface. In this example, we use the latter to create another proxy for the AccountService endpoint:

ServiceInterface is the remote business interface that our clients will use. WsdlDocumentUrl is the URL of WSDL file. Spring needs it as a starting point to create JAX-RPC services. NamespaceUri corresponds to the targetNamespace in the .wsdl file. ServiceName corresponds to the service name in the .wsdl file. PortName corresponds to the port number in the .wsdl file.

Now we can easily access the web service because we have a bean factory that can expose it as an AccountService interface. We can use this in Spring:

...

From the client code, we can access the web service as a normal class:

Public class AccountClientImpl {private AccountService service; public void setService (AccountService service) {this.service = service;} public void foo () {service.insertAccount (...);}}

Note: the above is slightly simplified because JAX-WS requires endpoint interfaces and implementation classes to use annotations such as @ WebService, @ SOAPBinding, etc. This means that you can't simply use normal Java interfaces and implementations as JAX-WS endpoints, you need to annotate them first. For details of these requirements, please refer to the JAX-WS documentation.

Using XFire to expose Web services

XFire is a lightweight SOAP library provided by Codehaus. XFire is exposed through XFire's own context, which will be combined with RemoteExporter-style bean, which needs to be added to your WebApplicationContext. For all the methods that allow you to expose the service, you need to create a DispatcherServlet class with the corresponding WebApplicationContext to encapsulate the service you are about to expose:

Xfire org.springframework.web.servlet.DispatcherServlet

You must also link to the XFire configuration. This is done by adding a context file to the contextConfigLocations parameter loaded by ContextLoaderListener (or ContextLoaderServlet).

ContextConfigLocation classpath:org/codehaus/xfire/spring/xfire.xml org.springframework.web.context.ContextLoaderListener

After you add a Servlet mapping (mapping / * to the XFire Servlet defined above), you only need to add an additional bean to use the XFire exposure service. For example, add the following configuration to 'xfire-servlet.xml':

XFire took care of other things. It checks your service interface and produces a WSDL file. Some of the documentation here is from the XFire website. To learn more about the integration of XFire Spring, visit docs.codehaus.org/display/XFIRE/Spring.

After reading the above, have you mastered how to talk about the method of collecting Web Service in Spring2.5? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report