基于CXF的webservice服务端和使用axis的客户接口,以及struts2下为什么无法访问webservice的原因及解决办法

本博文是在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.csdn.net/z793397795/article/details/85234887
如果无法调用,就把?wsdl去掉试试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值