首先这是借网上的一个超级简单的例子,该博客确实写得错值得看: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>
<!-- <!– 在这里仅仅为了开启懒加载 在一对多的时候可以使用–>-->
<!-- <settings>-->
<!-- <!– 打开延迟加载的开关 –>-->
<!-- <setting name="lazyLoadingEnabled" value="true"/>-->
<!-- <!– 将积极加载改为消极加载,即延迟加载 –>-->
<!-- <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