IDEA社區版本2019.3 , 用來創建接口包時需要做些額外操作。這裏使用Eureka作爲服務註冊中心,整個系統結構如下:
業務層 | VA-DICTATION-RT-BUS | 引入接口,使用服務 |
服務層 | VA-SERVICES-LOCATION | 引入接口,實現服務 |
數據層 |
MYSQL |
創建T_LOCATION表 |
相關步驟如下:
1、MYSQL:創建t_location表
CREATE TABLE `t_location` (
`f_id` int(11) NOT NULL AUTO_INCREMENT,
`f_userid` varchar(64) NOT NULL,
`f_create_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
`f_type` int(11) unsigned zerofill NOT NULL COMMENT '1、微信上報;2、用戶上報',
`f_latitude` float NOT NULL,
`f_longtitude` float NOT NULL,
`f_precision` float DEFAULT NULL COMMENT '微信上報時設置的:精度',
`f_scale` float DEFAULT NULL COMMENT '用戶上報時設置的:放大比例尺',
`f_lable` varchar(255) DEFAULT NULL COMMENT '用戶上報時設置的:poi',
PRIMARY KEY (`f_id`),
UNIQUE KEY `unique_index` (`f_userid`,`f_create_time`,`f_type`) USING BTREE,
KEY `index_userid` (`f_userid`,`f_create_time`) USING BTREE,
KEY `index_scope` (`f_latitude`,`f_longtitude`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8
2、IDEA創建服務接口項目,發佈到本地Maven,供其他系統通過座標引用。
接口項目主要三個文件,第一個是pom.xml,代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.net.mysoft.va.service.api</groupId>
<artifactId>service-api</artifactId>
<version>1.0.0</version>
<!--
這裏省略了,按你自己的項目來
.......
-->
<build>
<plugins>
<!-- 這個打包的jar,不能被其他項目引用,對於接口包來說簡直無用
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source> <!--指明源碼用的Jdk版本-->
<target>1.8</target> <!--指明打包後的Jdk版本-->
</configuration>
</plugin>
</plugins>
</build>
</project>
第二個是t_location對應的實體類
package cn.net.mysoft.va.service.api.location;
public class LocationEntity {
int f_id;
String f_userid;
String f_create_time;
int f_type;
float f_latitude;
float f_longtitude;
float f_precision;
float f_scale;
String f_lable;
public void setF_scale(float f_scale) {
this.f_scale = f_scale;
}
public int getF_type() {
return f_type;
}
public void setF_type(int f_type) {
this.f_type = f_type;
}
public void setF_latitude(float f_latitude) {
this.f_latitude = f_latitude;
}
public void setF_longtitude(float f_longtitude) {
this.f_longtitude = f_longtitude;
}
public float getF_longtitude() {
return f_longtitude;
}
public void setF_precision(float f_precision) {
this.f_precision = f_precision;
}
public float getF_precision() {
return f_precision;
}
public float getF_scale() {
return f_scale;
}
public float getF_latitude() {
return f_latitude;
}
public void setF_create_time(String f_create_time) {
this.f_create_time = f_create_time;
}
public String getF_create_time() {
return f_create_time;
}
public String getF_userid() {
return f_userid;
}
public String getF_lable() {
return f_lable;
}
public void setF_userid(String f_userid) {
this.f_userid = f_userid;
}
public void setF_lable(String f_lable) {
this.f_lable = f_lable;
}
public void setF_id(int f_id) {
this.f_id = f_id;
}
public int getF_id() {
return f_id;
}
@Override
public String toString() {
return "LocationEntity{" +
"f_id=" + f_id +
", f_userid='" + f_userid + '\'' +
", f_create_time='" + f_create_time + '\'' +
", f_type=" + f_type +
", f_latitude=" + f_latitude +
", f_longtitude=" + f_longtitude +
", f_precision=" + f_precision +
", f_scale=" + f_scale +
", f_lable='" + f_lable + '\'' +
'}';
}
}
第三個,基於Feign的服務接口定義類
package cn.net.mysoft.va.service.api.location;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient("VA-SERVICES-LOCATION")
// VA-SERVICES-EXERCISE 部署到tomcat的包名
@RequestMapping("/location")
public interface LocationService {
@RequestMapping(value = "/get/{uid}",method = RequestMethod.GET)
String getByUid(@PathVariable("uid") String uid);
/**
* 這裏是個糟糕的設計,必須選擇application/json,參數纔會傳遞出去。但是會對參數做編碼,導致服務方無法解析。 需要先轉義
* 後面嘗試使用text/html才搞定,與服務端的定義保持類一致
* @param bodystr
* @return
*/
@RequestMapping(value = "/set",method = RequestMethod.POST,
produces = {"text/html; charset=UTF-8"},
consumes = "text/html;charset=UTF-8")
String set(@RequestBody String bodystr);
}
3、IDEA基於嚮導建立Eureka服務,這裏沒有自定義安全與頁面,可不需要編碼,略。
4、編寫服務提供者模塊VA-SERVICES-LOCATION
第一步,修改POM.XML引入包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.net.mysoft.va.services</groupId>
<artifactId>va-serivices</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>va-serivices</name>
<description>va service for location,user,account...</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
</properties>
<dependencies>
<!-- ...... -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>cn.net.mysoft.va.service.api</groupId>
<artifactId>service-api</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
第二步,基本是Mybatis的工作,這裏直接上代碼
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.net.mysoft.va.services.location.LocationDao">
<select id="getByUid" resultType="cn.net.mysoft.va.service.api.location.LocationEntity" parameterType="String">
select f_id,
f_userid,
f_create_time,
f_type,
f_latitude,
f_longtitude,
f_precision,
f_scale,
f_lable
from t_location a
<where>
a.f_userid=#{uid}
</where>
order by f_create_time desc limit 100
</select>
<insert id="insert" parameterType="cn.net.mysoft.va.service.api.location.LocationEntity" keyProperty="f_id" useGeneratedKeys="true">
INSERT INTO t_account (
f_userid,
f_create_time,
f_type,
f_latitude,
f_longtitude,
f_precision,
f_scale,
f_lable
)
VALUES
(
#{f_userid},
now(),
#{f_type},
#{f_latitude},
#{f_longtitude},
#{f_precision},
#{f_scale},
#{f_lable}
);
</insert>
<!--
<update id="updateBalance" parameterType="cn.net.mysoft.va.dictation.services.exercise.mysql.account.AccountEntity">
update t_account a set
a.f_balance = #{balance},
a.f_modify_time=#{modifyTime},
a.f_ver=#{ver}+1,
a.f_sign=#{sign}
<where>
a.f_userid=#{userId} and a.f_ver=#{ver}
</where>
</update>
-->
</mapper>
Dao文件:
package cn.net.mysoft.va.services.location;
import cn.net.mysoft.va.service.api.location.LocationEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface LocationDao {
int insert(LocationEntity itm);
List<LocationEntity> getByUid(@Param("uid")String uid);
}
第三步,實現接口LocationService
package cn.net.mysoft.va.services.location;
import cn.net.mysoft.va.service.api.commonlib.RequestMessage;
import cn.net.mysoft.va.service.api.commonlib.ResponseMessage;
import cn.net.mysoft.va.service.api.location.LocationEntity;
import cn.net.mysoft.va.service.api.location.LocationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class LocationServiceImpl implements LocationService {
@Autowired
LocationDao objLocationDao;
public static final Logger logger = LoggerFactory.getLogger("va_servies_log");
@Override
public String getByUid(String uid) {
logger.info("..."+uid);
List<LocationEntity> lstLocationEntity = objLocationDao.getByUid(uid);
if(lstLocationEntity == null)
return ResponseMessage.toJsonString(new ResponseMessage(-1,"db null"));
return ResponseMessage.toJsonString(new ResponseMessage(0,"ok",lstLocationEntity));
}
@Override
public String set(String bodystr) {
logger.info("...");
// parse from request body :
RequestMessage<LocationEntity> objRequestMessage =
RequestMessage.fromJsonString(bodystr,LocationEntity.class);
if(objRequestMessage == null) {
return ResponseMessage.toJsonString(new ResponseMessage(-1, "paras invalid"));
}
if(objRequestMessage.getMapParas().size() < 1)
return ResponseMessage.toJsonString(new ResponseMessage(-1,"one or more record data should be provided."));
int iRowCount = 0;
for(LocationEntity itm:objRequestMessage.getMapParas().values()){
logger.info("...");
iRowCount += objLocationDao.insert(itm);
}
return ResponseMessage.toJsonString(new ResponseMessage(0,"Insert record number is :"+iRowCount));
}
}
這裏有兩個打包文件(應該採用自定義配置,與Feign進一步集成),有需要的可加QQ(7457222)留言,交流。
第四步,配置文件properties,編譯後,註冊到Eureka。
# Eureka服務註冊中心的地址,用於client與server進行交流
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka/
# 用ip註冊進系統,這兩個很必需
eureka.instance.hostname=location-service
eureka.instance.preferIpAddress=true
# InstanceId採用了隨機數,確保了獨一無二
eureka.instance.instance-id=${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
# 服務名
spring.application.name=va-services-location
# 提供者的服務端口
#server.port=8081
5、在服務使用方VA-DICTATION-RT-BUS調用
第一步,修改pom.xml,增加對接口的引用
<!-- 增加用戶與賬戶接口定義模塊 -->
<dependency>
<groupId>cn.net.mysoft.va.service.api</groupId>
<artifactId>service-api</artifactId>
<version>1.0.0</version>
</dependency>
第二步,在入口類添加註解
@EnableFeignClients(basePackages = {"other.api","cn.net.mysoft.va.service.api"})
第三步,調用
@Test
void locationAPI2Service(){
try {
String res = objLocationService.getByUid("owrjxwq3Dt1Q-VMHZG4Absj6xIGc");
System.out.println(res);
}catch(Exception exp){
System.out.println(exp.getMessage());
}
}
以上,如果有不通,或者優化建議,歡迎留言。