WebService的使用备忘

WebService的使用备忘


Android端需要的Jar
ksoap2的下载地址,现在下载积分很贵啊,反正我是没有积分。
https://github.com/simpligility/ksoap2-android/releases

  为了方便这里先自行准备个接口用来练习。

一、制作WebService接口(准备工作,如果只看请求此处可以跳过)

  这里我使用的IntelliJ IDEA创建的后台项目。用的JDK1.8,转Kotlin项目直接用的IDE提示的方式进行转换的。需要在pom.xml添加上以下两个依赖:


<dependency>
    <groupId>org.jetbrains.kotlingroupId>
    <artifactId>kotlin-reflectartifactId>
    <version>${kotlin.version}version>
dependency>

<dependency>
    <groupId>org.apache.cxfgroupId>
    <artifactId>cxf-spring-boot-starter-jaxwsartifactId>
    <version>3.2.5version>
dependency>

1.设置接口的功能

  这里准备一个实体类,用来当返回数据用,后台程序入口代码就不贴出来了。

/**
 * 测试数据
 * msg : 内容
 * date : 日期
 */
data class Message(val msg : String , val date : String)

接下来定义一下接口的功能,这里准备返回JSON字符串,所以返回类型设成了String(这种先写接口,再写实现的方式。让我想起了C++创建类的时候的先写.h声明,再写.cpp文件实现。顿时有种感觉很有道理,又说不清楚的感觉- -!)。代码如下:

import javax.jws.WebMethod
import javax.jws.WebService
/**
 * 定义接口
 */
@WebService
interface TestService {
    @WebMethod(action = "http://service.test.lyan.com/getMsg")
    fun getMsg(): String
}

  实现接口的具体功能,返回一条Json格式的数据。具体实现如下:

import com.fasterxml.jackson.databind.ObjectMapper
import com.lyan.test.bean.Message
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import javax.jws.WebService
/**
 * 调用的接口
 */
@Component
@WebService(endpointInterface = "com.lyan.test.service.TestService",
        serviceName = "TestService", targetNamespace = "http://service.test.lyan.com/")
class TestImpl : TestService {

    @Autowired
    private lateinit var objectMapper: ObjectMapper

    /**
     * 客户端调用的方法
     */
    override fun getMsg(): String =
            objectMapper.writeValueAsString(
                    Message("测试内容", LocalDate.now().format(
                            DateTimeFormatter.ofPattern("yyyy-MM-dd"))))

}

2.发布接口的配置

import com.lyan.test.service.TestService
import org.apache.cxf.Bus
import org.apache.cxf.jaxws.EndpointImpl
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import javax.xml.ws.Endpoint

/**
 * 用来发布接口的配置
 */
@Configuration
open class CxfConfig {
    @Autowired
    private lateinit var testService: TestService
    @Autowired
    private lateinit var bus : Bus
    /**
     * 发布测试接口
     */
    @Bean open fun testEndpoint(): Endpoint = EndpointImpl(bus,testService).apply { publish("/TestService") }

}

  接下来运行SpringBoot项目,请求这个本地地址http://localhost:8080/services。不出意外肯定会出现下面这个页面(圈中的部分就是发布的接口):
WebService的使用备忘_第1张图片
  点击这个链接,就会跳到下面这个页面,圈中的部分就是我们请求的url地址,也就是我们通常请求的url就是这么来的:
WebService的使用备忘_第2张图片
  到这里准备工作已经完成,接下来就是在android端中调用这个接口,获取数据了。


二、在Android中请求WebService接口(如果只想知道数据是怎么来的可以忽略此处)

  在Android工程里别忘了添加ksoap2的Jar包和请求网络的权限。这里为了装逼就没用线程去做异步请求用的协程,既然是练习还是用线程的话感觉实在是太low了。用到的依赖如下(具体版本去Anko的Github里找就行):

implementation "org.jetbrains.anko:anko-commons:$anko_version"
implementation "org.jetbrains.anko:anko-coroutines:$anko_version"

下面这个配置最好也加上,加上后跟协程有关的代码会看的舒服一些 
kotlin { experimental { coroutines ‘enable’ } }


  接下来就实现网络请求的功能就可以了,主要功能就是将请求到的数据展示在弹窗中。

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.alert
import org.jetbrains.anko.coroutines.experimental.bg
import org.jetbrains.anko.info
import org.ksoap2.SoapEnvelope
import org.ksoap2.serialization.SoapObject
import org.ksoap2.serialization.SoapSerializationEnvelope
import org.ksoap2.transport.HttpTransportSE

/**
 * 网络请求测试界面
 */
class MainActivity : AppCompatActivity() ,AnkoLogger{

    private val NAMESPACE = "http://service.test.lyan.com/"
    private val METHOD_NAME = "getMsg"
    private val SOAP_ACTION = "$NAMESPACE$METHOD_NAME"
    private val URL = "http://192.168.3.224:8080/services/TestService?wsdl"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        /**
         * 点击按钮后进行网络数据的请求
         * getData 按钮控件的id
         */
        getData.setOnClickListener {
            launch(UI) {
                val result = bg { downLoad() }.await()
                info{"返回内容 -> $result"}
                alert { message = result }.show()
            }
        }
    }

    /**
     * 请求WebService接口
     */
    private fun downLoad(): String {
        val request = SoapObject(NAMESPACE, METHOD_NAME)
        val envelope = SoapSerializationEnvelope(SoapEnvelope.VER11)
        envelope.setOutputSoapObject(request)
        val transportSE = HttpTransportSE(URL)
        transportSE.call(SOAP_ACTION, envelope)
        return envelope.response.toString()
    }

}

  运行的结果如下所示:
WebService的使用备忘_第3张图片

三、携参数请求Webservice接口

  之前只是普通的请求,那如果有上传参数怎么办呢。接下来对代码改造一下。

1.后台部分

  在后台部分对接口的定义和实现改造一下,让getMsg()这个方法能接收参数,改造后如下:

/**
 * 接口
 */
@WebService
interface TestService {
    @WebMethod(action = "http://service.test.lyan.com/getMsg")
    fun getMsg(@WebParam(name = "msg") message : String): String
}

  在实现中就是将上传的参数,添加到返回的数据中,然后再返还给客户端。具体代码如下:

/**
 * 实现
 */
@Component
@WebService(endpointInterface = "com.lyan.test.service.TestService",
        serviceName = "TestService", targetNamespace = "http://service.test.lyan.com/")
class TestImpl : TestService {

    @Autowired
    private lateinit var objectMapper: ObjectMapper

    /**
     * 客户端调用的方法
     */
    override fun getMsg(message : String): String =
            objectMapper.writeValueAsString(
                    Message(message, LocalDate.now().format(
                            DateTimeFormatter.ofPattern("yyyy-MM-dd"))))

}

2.Android部分

  Android这部分很好改,就是在请求的时候通过SoapObject的addProperty()方法添加参数就行了。

/**
 * 请求WebService接口
 */
private fun downLoad(): String {
    val request = SoapObject(NAMESPACE, METHOD_NAME)
    request.addProperty("msg" , "来自客户端的数据")//添加的上传参数
    val envelope = SoapSerializationEnvelope(SoapEnvelope.VER11)
    envelope.setOutputSoapObject(request)
    val transportSE = HttpTransportSE(URL)
    transportSE.call(SOAP_ACTION, envelope)
    return envelope.response.toString()
}

  最后来看一下运行的结果,别忘了后台程序也重新运行一下。
WebService的使用备忘_第4张图片

你可能感兴趣的:(Android学习笔记)