本博文是在strtus2环境下开发的webservice接口,为什么单独把strtus2环境开发的接口拿出来做记录,是因为,在开发的过程中踩了几个坑,以此来纪念一下。
1、准备CXF相关jar包,这个可以百度搜索下载。
官网下载网址:
http://cxf.apache.org/download.html
主要jar:
pom:
2、在当前项目建个webservice包名,并书写接口和实现类:
接口目录:
IDetectionInformation:
package com.kerun.app.webservice;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* @author zxy
*/
@WebService(targetNamespace="http://webservice.app.kerun.com")
public interface IDetectionInformation {
public String saveDetectionInformation(@WebParam(name="detectionInfo") String detectionInformation);
}
DetectionInformationImpl:
package com.kerun.app.webservice.impl;
import javax.jws.WebParam;
import javax.jws.WebService;
import org.springframework.stereotype.Component;
import com.kerun.app.webservice.IDetectionInformation;
import com.kerun.sys.dao.GenericDAOImpl;
/**
* @author zxy
*/
@Component("webservice")
@WebService(endpointInterface = "com.kerun.app.webservice.IDetectionInformation",
serviceName="detectionInformation" ,
targetNamespace="http://webservice.app.kerun.com")
public class DetectionInformationImpl extends GenericDAOImpl<java.io.Serializable> implements IDetectionInformation{
public String saveDetectionInformation(@WebParam(name="detectionInfo") String detectionInformation) {
return detectionInformation;
}
}
在这里第一个坑就是,当接口和实现类不在一个包下时,在发布接口的时候会出现targetNamespace不一致的情况,这一情况会导致发布的接口中没有参数描述,进而无法传递参数。
解决办法:
强制使两个类的targetNamespace一致即可,即增加targetNamespace参数,写死targetNamespace,如我写的就是“http://webservice.app.kerun.com”
3、定义CXF文件:applicationContext-ws.xml
单独定义xml文件时,要查一下web.xml配置,是否能扫描到当前定义的文件,如下配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext*.xml
</param-value>
</context-param>
applicationContext-ws.xml内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd"
default-lazy-init="true">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint id="saveDetectionInfo"
implementor="#webservice"
address="/saveDetectionInfo" />
</beans>
#webservice为我们上面接口实现类的别名(@Component(“webservice”),忘记的话,往上看)
address为我们发布接口后访问的地址,如:http://127.0.0.1:8080/demo/webservice/saveDetectionInfo?wsdl
4、配置web.xml
web.xml中增加CXF内容:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
这一步配置完毕后就可以发布接口了,但是会出现一个问题,就是当你访问发布的接口时,会被strtus2拦截,因为原来在web.xml中,struts2过滤了/*,即把根目录下得所有目录都进行了过滤,而webservice的目录我定义为/webservic/⭐,这样一来,客户端访问该web服务的时候就被strust2过滤器当成无效链接过滤了。因此,修改struts2 dispatcher的内容,因为dispatcher里面有个方式dofilter,他的功能是把过滤请求传递给下面一个过滤器,这样就把当前的请求放行了。
下面是我们重写struts2的FilterDispatche类的内容:
package com.kerun.sys.util;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;
/**
* @author zxy
* 因为原来在web.xml中,struts2过滤了/*,即把根目录下得所有目录都进行了过滤,
* 而webservice的目录我定义为/ws/*,这样一来,客户端访问该web服务的时候就被strust2过滤器当成无效链接过滤了。
* 因此,修改struts2 dispatcher的内容,因为dispatcher里面有个方式dofilter,他得功能是把过滤请求传递给下面一个过滤器,
* 这样就把当前的请求放行了。
* */
public class FilterDispatcherKerun extends StrutsPrepareAndExecuteFilter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
if(request.getRequestURI().contains("/webservice/")){
chain.doFilter(req,res);
}else{
super.doFilter(req, res, chain);
}
}
}
5、修改web.xml中的配置为我们上面重写的类
修改前:
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
修改后:
<filter>
<filter-name>struts2</filter-name>
<filter-class>
com.kerun.sys.util.FilterDispatcherKerun</filter-class>
</filter>
好了,到这一步发布的接口就可以使用啦。
客户端调用方式,请移步:https://blog.youkuaiyun.com/z793397795/article/details/85234887
如果无法调用,就把?wsdl去掉试试。