webService(三 springboot的restful、http協議)

首先這是借網上的一個超級簡單的例子,該博客確實寫得錯值得看:https://blog.csdn.net/qq_34446485/article/details/79669134

上次學習了webservice的wsdl的saop協議的風格,對比一下:RESTful 簡化了 web service 不再需要 wsdl ,也不再需要 soap 協議,而是通過最簡單的 http 協議傳輸數據 ( 包括 xml 或 json) 。既簡化了設計,也減少了網絡傳輸量(因爲只傳輸代表數據的 xml 或 json ,沒有額外的 xml 包裝)。

先建一個數據庫


SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(10) NOT NULL,
  `name` varchar(100) DEFAULT NULL,
  `sex` char(6) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '李斯', '男', '江西南昌', '22');

創建springboot項目,導入依賴

  <dependencies>
        <!-- 提供JacksonJsonProvider,非必需,學過jersey,所以在這塊直接使用了,可以使用其他json轉化替換,使用cxf的有很多問題,沒法填 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
            <version>3.1.11</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.25</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>3.1.6</version>
        </dependency>
    </dependencies>

開始編寫:

一、實體類

package cn.cj.webservicerestful.entity;

import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;

/**
 * 學生實體類
 */
//用於轉換
@XmlRootElement(name = "Student")
public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String name;
    private char sex;
    private String address;
    private Integer age;

    public Student() {
        super();
    }

    public Student(Integer id, String name, char sex, String address,
                   Integer age) {
        super();
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.address = address;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", sex=" + sex
                + ", address=" + address + ", age=" + age + "]";
    }

}

二、整合SpringBoot mybatis

#server port set
server.port:8080
#mysql datasource set
spring.datasource.
spring.datasource.url=jdbc:mysql://localhost:3306/cxfdemo?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis.typeAliasesPackage=cn.cj.webservicerestful.entity
mybatis.mapperLocations=classpath\:mapper/*.xml
mybatis.config-location=classpath\:mybatis-config.xml
spring.jackson.serialization.indent_output=true
logging.level.org.springframework.web=WARN
#logging.file = C\:\\web\\temp\\log\\log.log
logging.level.org.springframework=WARN
logging.level.cn.edu.jxnu.dao=INFO
logging.level.cn.edu.jxnu.resource=WARN

可以加入mybatis的一些配置,懶加載

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<!--    &lt;!&ndash; 在這裏僅僅爲了開啓懶加載 在一對多的時候可以使用&ndash;&gt;-->
<!--    <settings>-->
<!--        &lt;!&ndash; 打開延遲加載的開關 &ndash;&gt;-->
<!--        <setting name="lazyLoadingEnabled" value="true"/>-->
<!--        &lt;!&ndash; 將積極加載改爲消極加載,即延遲加載 &ndash;&gt;-->
<!--        <setting name="aggressiveLazyLoading" value="false"/>-->
<!--        <setting name="cacheEnabled" value="true"/>-->
<!--    </settings>-->

</configuration>

dao 層 mapper接口

package cn.cj.webservicerestful.dao;

import cn.cj.webservicerestful.entity.Student;
import org.apache.ibatis.annotations.Param;

/**
 * dao層數據操作接口
 *
 */
public interface StudentDao {

    Student getStudentById(@Param("id") Integer id);
}

StudentMapper.xml mapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.cj.webservicerestful.dao.StudentDao">
    <resultMap type="cn.cj.webservicerestful.entity.Student" id="Student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <result property="age" column="age"/>
    </resultMap>
    <!-- 定義字段集合 -->
    <sql id="studentInformation">
        id,name,sex,address,age
    </sql>
    <select id="getStudentById" resultMap="Student" flushCache="true"
            parameterType="java.lang.Integer">
        select
        <include refid="studentInformation"/>
        from student where id=#{id}
    </select>
    <!-- 刷新間隔 -->
    <cache flushInterval="600000"/>
</mapper>

配置SpringBoot掃描dao【自動掃描,和註冊配置】

package cn.cj.webservicerestful;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Controller;

/**
 * 啓動類
 */
@Controller
@MapperScan("cn.cj.webservicerestful.dao")
@SpringBootApplication
// / 沒有這個rest失效 只存在soap
@ImportResource(locations = {"classpath:cxf-config.xml"})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

三、重點 整合cxf webService【注意,不是restful,而是webservice 基於soap的】

package cn.cj.webservicerestful;

import org.springframework.context.annotation.Configuration;

@Configuration
public class CxfConfig {
    //cxf配置類【因爲是使用SpringBoot,所以使用類和註解配置】
    //Spring boot 默認是不支持 JSP 的,所以想用 JSP 就必須使用外部容器來運行,即不能使用嵌入式的 Tomcat 或 Jetty。有時候一些老項目使用的是 JSP 寫的頁面,後臺使用的是 Servlet
    @Bean
    public ServletRegistrationBean newServlet() {
        return new ServletRegistrationBean(new CXFServlet(), "/cxf/*");
    }
//在springcould中是消息總線的意思
    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    /**
     * @return
     */
    @Bean
    @Qualifier("studentServiceImpl") // 注入webService
    public Endpoint endpoint(StudentServiceImpl studentServiceImpl) {
        EndpointImpl endpoint = new EndpointImpl(springBus(), studentServiceImpl);
        endpoint.publish("/webService");// 暴露webService api
        return endpoint;
    }

    @Bean("jsonProvider") // 構造一個json轉化bean,用於將student轉化爲json
    public JacksonJsonProvider getJacksonJsonProvider() {
        return new JacksonJsonProvider();

    }
}

寫了一個Spring Controller說明這是直接走前端控制器,若沒有cxf

package cn.cj.webservicerestful;

import cn.cj.webservicerestful.entity.Student;
import cn.cj.webservicerestful.service.StudentService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * Spring 前端控制
 * 即
 *當沒有cxf的時候,直接走dispatherServlet前端控制器
 * 通過這個返回正確,作對比
 *
 */
@Controller
public class SpringController {

    @Autowired
    private StudentService studentRestfulService;

    @ResponseBody
    //produces:指定響應體返回類型和編碼
    @Produces({MediaType.APPLICATION_JSON + "charset='utf-8'"})
    @RequestMapping(value = "get/{id}", method = RequestMethod.GET)
    public String getStudent(@PathVariable("id") Integer id) {
        Student student = studentRestfulService.getStudent(id);
        Object json = JSONObject.toJSON(student);
        return json.toString();
    }
}

這裏使用ip:port/get/1 即可獲取【@PathVariable 是Spring的 與PathParam 是JSR-RS的功能類似】返回了json 數據

編寫webservice 接口

package cn.cj.webservicerestful.service;

import cn.cj.webservicerestful.entity.Student;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 * @author liguobin
 * @description WebService接口定義 soap
 */
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) // 返回類型
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) // 請求類型
@WebService
public interface StudentService {

    /**
     * 查找一個學生
     *
     * @param id
     * @return
     */
    @WebMethod
    public Student getStudent(@WebParam(name = "id") Integer id);

}

實現service

package cn.cj.webservicerestful.serviceImpl;

import cn.cj.webservicerestful.dao.StudentDao;
import cn.cj.webservicerestful.entity.Student;
import cn.cj.webservicerestful.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.jws.WebService;

/**
 * 實現webservice接口,對外暴露 soap
 */
@Component//由Spring管理
@WebService(endpointInterface = "cn.cj.webservicerestful.service.StudentService") // webservice接口的全類名
public class StudentServiceImpl implements StudentService {

    /**
     * 注入spring bean
     */
    @Autowired
    private StudentDao studentDao;

    @Override
    public Student getStudent(Integer id) {
        return studentDao.getStudentById(id);
    }
}

測試webservice
輸入http://localhost:8082/cxf 【查看所以soap和restful api】

單獨查看某一個soap api【http://localhost:8082/cxf/webService?wsdl】 在前文 endpoint.publish("/webService");// 就是這個webService

四、整合Restful api【 RESTful services】

package cn.cj.webservicerestful.resource;

import cn.cj.webservicerestful.entity.Student;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

/**
 * @author: liguobin
 * @Description:
 * @時間: 2018-3-7 下午3:59:15
 * @version: V1.0
 */
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public interface StudentInterface {

    /**
     * @param id
     * @return
     */
    @GET
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    @Path("/getone/{id:[0-9]{0,10}}") // 限制id只能是0~9的數組 不超過10位
    public Student getStudent(@PathParam("id") Integer id);

    }

實現rest接口

package cn.cj.webservicerestful.resource;

import cn.cj.webservicerestful.entity.Student;
import cn.cj.webservicerestful.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/")
public class StudentInterfaceImpl implements StudentInterface {

    @Autowired
    private StudentService studentService;

    // 獲取json
    @Override
    @GET
    @Path("/getjson/{id:[0-9]{0,10}}")
    @Produces({MediaType.APPLICATION_JSON})
    public Student getStudent(@PathParam("id") Integer id) {
        return studentService.getStudent(id);
    }

    // 獲取xml
    @GET
    @Path("/getxml/{id}")
    @Produces({MediaType.APPLICATION_XML})
    public Student getStudent2(@PathParam("id") Integer id) {
        return studentService.getStudent(id);
	}
}

配置cxf的【@ImportResource(locations = { “classpath:cxf-config.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:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
    <!-- 將Bean託管給Spring -->
    <bean id="studentService" class="cn.cj.webservicerestful.resource.StudentInterfaceImpl">
    </bean>
    <!-- 配置需要暴露的BeanService -->
    <jaxrs:server id="restContainer" address="/students"> <!-- 暴露restful api 類似於前文提到的webService【暴露soap】 -->
        <jaxrs:serviceBeans>
            <!-- 相當於打包發佈服務 -->
            <ref bean="studentService"/>
        </jaxrs:serviceBeans>
        <!-- 提供一個json轉化,沒有這個不能自動返回json jsonProvider就是前面@Bean生成的在CxfConfig -->
        <jaxrs:providers>
            <ref bean="jsonProvider"/>
        </jaxrs:providers>
    </jaxrs:server>
</beans>  

查看RestFul api

瀏覽器輸入http://localhost:8082/cxf/ 就可以查看到多了 Available RESTful services:Endpoint address: http://localhost:8082/cxf/students

【因爲soap和restful均是cxf處理】

最後測試restful請求

輸入http://localhost:8082/cxf/students/getjson/1 獲取json數據
輸入http://localhost:8082/cxf/students/getxml/1 獲取xml數據

參考地址:github 源碼:https://github.com/jxnu-liguobin/SpringBoot-CXF-demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章