Springboot+webService 接口开发

一,webservice是什么?

网上的解释很多,其实就是跨语言和操作系统的的远程调用技术。比如亚马逊,可以将自己的服务以webservice的服务形式暴露出来,我们就可以通过web调用这些,无论我们使用的语言是java还是c,这也是SOA应用一种表现形式。

WSDL(Web Services Description Language)将无论用何种语言书写的web service描述出来,比如其参数或返回值。WSDL是服务端和客户端都能解读的标准格式。客户端通过URL地址访问到WSDL文件,在调用服务端之前先访问WSDL文件。 读取到WSDL后通过客户端的API类可以生成代理类,调用这些代理类就可以访问webservice服务。代理类将客户端的方法变为soap(Simple Object Access Protocol,可以理解为http+xml)格式通过http发送,同时接受soap格式的返回值并解析。

二,接口开发

  2.1,pom.xml 依赖

     重点:这里注意一下你的  springboot 版本,不同的版本 cxf 的写法不同  我这里是  2.0.8 版本

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

  2.2,cxf依赖:

 <!-- webservice cxf -->
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
      <version>3.3.3</version>
    </dependency>

  2.3 , 服务端:

   endpoint.getInInterceptors().add(new WsInterceptor());

  此处只是加了特殊过滤器,无需要可以注释

import com.techhero.platform.api.service.GfService;
import com.techhero.platform.api.service.Impl.GfServiceImpl;
import com.techhero.platform.api.util.WsInterceptor;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.xml.ws.Endpoint;

/**
 * @ClassName CxfConfig
 * @Description: cxf 发布所有接口至服务
 * @Author wuchao
 * @Date 2020/1/13
 * @Version V1.0
 **/
@Configuration
public class CxfConfig {

    /*springboot 2.0.6版本之后写法改为配置文件*/
   /* @Bean
    public ServletRegistrationBean dispatcherServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFServlet(), "/util/*");
        servletRegistrationBean.setName("GfService");
        return servletRegistrationBean;
    }*/

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    @Bean
    public GfService gfJsonService() {
        return new GfServiceImpl();
    }

    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), gfJsonService());
        endpoint.publish("/api");
        endpoint.getInInterceptors().add(new WsInterceptor());
        return endpoint;
    }

}

 Springboot2.0.6 版本之后,  请在你的 bootstrap.yml 文件  在上这句话,并且注释 ServletRegistrationBean dispatcherServlet()方法, 请看上面 注释

cxf:
  path: /GfService
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.AbstractLoggingInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.io.DelegatingInputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.logging.Logger;

/**
 * @ClassName WsInterceptor
 * @Description: 过滤器
 * @Author wuchao
 * @Date 2020/1/13
 * @Version V1.0
 **/
public class WsInterceptor extends AbstractLoggingInterceptor {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WsInterceptor.class);


    public WsInterceptor() {
        super(Phase.RECEIVE);
    }


    @Override
    protected Logger getLogger() {
        return null;
    }

    @Override
    public void handleMessage(Message message) throws Fault {
        InputStream is = message.getContent(InputStream.class);
        if (is != null) {
            CachedOutputStream bos = new CachedOutputStream();
            if (threshold > 0) {
                bos.setThreshold(threshold);
            }
            try {
                // 使用适当的输入流并在以后还原
                InputStream bis = is instanceof DelegatingInputStream ? ((DelegatingInputStream) is).getInputStream() : is;

                //仅复制到最大限制,因为这就是我们需要记录的全部
                //我们可以流剩下的
                IOUtils.copyAtLeast(bis, bos, limit == -1 ? Integer.MAX_VALUE : limit);
                bos.flush();
                bis = new SequenceInputStream(bos.getInputStream(), bis);

                // 恢复委托输入流或输入流
                if (is instanceof DelegatingInputStream) {
                    ((DelegatingInputStream) is).setInputStream(bis);
                } else {
                    message.setContent(InputStream.class, bis);
                }

                bos.close();
            } catch (IOException e) {
                throw new Fault(e);
            } finally {
                LOGGER.info(bos.toString());
            }
        }

    }
}

 

2.4,接口

/**
 * @ClassName gfService
 * @Description: TODO
 * @Author wuchao
 * @Date 2020/1/13
 * @Version V1.0
 * @WebService 使接口为webService接口
 * @name 暴露服务名称
 * @targetNamespace 命名空间, 一般是接口的包名倒序
 **/
@WebService(name = "GfService", targetNamespace = "http://service.api.platform.techhero.com")
public interface GfService {

    /**
     * 获取八大类型接口
     *
     * @param model
     * @param czsj
     * @param num
     * @return
     */
    @WebMethod
    String getBusinessData(@WebParam(name = "model") String model, @WebParam(name = "czsj") Date czsj, @WebParam(name = "num") int num);

}
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.techhero.platform.api.entity.ModelXml;
import com.techhero.platform.api.service.GfService;
import com.techhero.platform.api.util.WebUtil;

import javax.jws.WebService;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName GfServiceImpl
 * @Description: TODO
 * @Author wuchao
 * @Date 2020/1/13
 * @Version V1.0
 * @WebService 使接口为webService接口
 * @serviceName 与接口中指定的name一致
 * @targetNamespace 命名空间, 一般是接口的包名倒序
 * @endpointInterface 接口地址
 **/
@WebService(serviceName ="GfService",targetNamespace="http://service.api.platform.techhero.com",
            endpointInterface="com.techhero.platform.api.service.GfService")
public class GfServiceImpl implements GfService {

    /**
     * 获取八大类型接口
     *
     * @param model
     * @param czsj
     * @param num
     * @return
     */
    @Override
    public String getBusinessData(String model, Date czsj, int num) {
       /*此处业务逻辑*/
        return null;
    }

}

2.4 ,客服端 

 

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.junit.Test;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;


/**
 *@ClassName WebServerTest 客服端测试类
 *@Description: TODO
 *@Author wuchao
 *@Date 2020/1/13
 *@Version V1.0
 **/
public class WebServiceTest {

    @Test
    public void testSend1(){

        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://localhost:9099/GfService/api?wsdl");
        // 需要密码的情况需要加上用户名和密码
        // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
        Object[] objects = new Object[0];
        try {
            //Date作为参数传递时需要转化为XMLGregorianCalendar类型

            Date date = parseDate("2019-08-01 09:28:00","yyyy-MM-dd HH:mm:ss");
            GregorianCalendar cal = new GregorianCalendar();
            cal.setTime(date);
            XMLGregorianCalendar xmlDate = null;
            try {
                xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
            } catch (Exception e) {

                e.printStackTrace();
            }
            // invoke("方法名",参数1,参数2,参数3....);
            /*获取八大类型*/
            //objects = client.invoke("getBusinessData", "300002001",xmlDate,-1);
            /*获取年度目标值*/
            //objects = client.invoke("notifyYearData", "2019-04-01","1000","014043");
            /*获取月度目标值*/
            objects = client.invoke("getMonthData", "2019-04-01");
            System.out.println( objects[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Date parseDate(String dateStr, String parseStyle) {
        Date date = null;
        if (null != parseStyle && !"".equals(parseStyle.trim()) && null != dateStr && !"".equals(dateStr.trim())) {
            SimpleDateFormat sdf = new SimpleDateFormat(parseStyle);
            try {
                date = sdf.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return date;
    }

2.5, 有问题,我们可以一起交流,qq770149701

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可乐cc呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值