添加代码示例springboot-swagger2

This commit is contained in:
yidao620 2018-02-27 18:01:58 +08:00
parent f555cb345f
commit 27bd847e21
25 changed files with 1389 additions and 2 deletions

View File

@ -63,7 +63,7 @@ spring:
datasource:
url: jdbc:mysql://123.207.66.156:3306/pos?useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8
username: root
password: _EnZhi123
password: ******
thymeleaf:
cache: false
@ -94,7 +94,7 @@ spring:
datasource:
url: jdbc:mysql://123.207.66.156:3306/pos?useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8
username: root
password: _EnZhi123
password: ******
thymeleaf:
cache: false

17
springboot-swagger2/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
# 此为注释– 将被Git 忽略
# /结尾表示是目录,忽略目录和目录下的所有件
# /开头表示根目录,否则是.gitignore的相对目录
# !开头表示反选
.idea/
target/
*.iml
*.ipr
*.iws
*.log
.svn/
.project
rebel.xml
.rebel-remote.xml.*
swagger.json
swagger.adoc

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 Xiong Neng
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,10 @@
## 简介
集成Swagger2自动生成API文档同时可转换成PDF格式
## 许可证
Copyright (c) 2018 Xiong Neng
基于 MIT 协议发布: <http://www.opensource.org/licenses/MIT>

143
springboot-swagger2/pom.xml Normal file
View File

@ -0,0 +1,143 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xncoding</groupId>
<artifactId>springboot-swagger2</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-swagger2</name>
<description>集成Swagger2</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<!-- swagger2 集成-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.xncoding</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.pegdown</groupId>
<artifactId>pegdown</artifactId>
<version>1.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup</artifactId>
<version>1.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<!--<proc>none</proc>-->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<systemPropertyVariables>
<swaggerOutputDir>${project.basedir}/src/main/resources/swagger</swaggerOutputDir>
<asciiDocOutputDir>${project.basedir}/src/main/resources/swagger/swagger</asciiDocOutputDir>
</systemPropertyVariables>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@ -0,0 +1,72 @@
#!/bin/bash
# 项目自动更新脚本
# 先clone相应的分支下来
# git clone ssh://git@120.24.173.142:7999/xxx.git
# 远程调试启动:
# nohup java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 &
function start {
profile="$1"
echo "启动环境profile=${profile}"
jarfile=$(ls target/*.jar)
if [[ "$?" == "0" ]]; then
stop $profile $jarfile
fi
branch=$(git branch |awk '{print $2}')
git pull origin ${branch}
echo "更新完代码开始重新打包"
mvn clean && mvn clean && mvn package -DskipTests=true
if [[ "$?" != "0" ]]; then
echo "编译出错,退出!"
exit 1
fi
echo "nohup java -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 &"
nohup java -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 &
echo "启动应用中,请查看日志文件..."
}
function stop {
profile="$1"
jarfile="$2"
ps aux | grep "${jarfile}" | grep "spring.profiles.active=${profile}" | grep -v grep > /dev/null
if [[ "$?" == "0" ]]; then
echo "该应用还在跑,我先停了它"
pid=$(ps aux | grep "${jarfile}" | grep "spring.profiles.active=${profile}" | grep -v grep |awk '{print $2}')
if [[ "$pid" != "" ]]; then
kill -9 $pid
fi
echo "停止应用成功..."
fi
}
if [[ "$1" == "start" ]]; then
if [[ "$#" < 2 ]]; then
echo "请输入正确参数:./epay.sh start {profile}"
exit 1
fi
profile="$2"
if [[ "$profile" != "dev" && "$profile" != "test" && "$profile" != "show" && "$profile" != "production" ]]; then
echo "参数错误请输入正确的profile参数使用方法"
echo "./epay.sh start {profile} ==> 启动应用,{profile}取值dev|test|show|production"
exit 1
fi
start "${profile}"
elif [[ "$1" == "stop" ]]; then
if [[ "$#" < 2 ]]; then
echo "请输入正确参数:./epay.sh stop {profile}"
exit 1
fi
profile="$2"
if [[ "$profile" != "dev" && "$profile" != "test" && "$profile" != "show" && "$profile" != "production" ]]; then
echo "参数错误请输入正确的profile参数使用方法"
echo "./epay.sh stop {profile} ==> 停止应用,{profile}取值dev|test|show|production"
exit 1
fi
jarfile=$(ls target/*.jar)
stop $profile $jarfile
else
echo "参数错误,使用方法:{}参数是必填的,[]参数可选"
echo "./epay.sh start {profile} ==> 启动应用,{profile}取值dev|test|show|production"
echo "./epay.sh stop {profile} ==> 停止应用,{profile}取值dev|test|show|production"
exit 1
fi

View File

@ -0,0 +1,12 @@
package com.xncoding.jwt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,34 @@
package com.xncoding.jwt.api;
import com.xncoding.jwt.api.model.BaseResponse;
import io.swagger.annotations.Api;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
/**
* 注意这个统一异常处理器只对认证过的用户调用接口中的异常有作用对AuthenticationException没有用
*/
@RestControllerAdvice
@Api(value = "机具管理API接口类", tags = "机具管理接口", description = "提供POS机的入网和监控的统一管理")
public class ExceptionController {
// 捕捉其他所有异常
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse globalException(HttpServletRequest request, Throwable ex) {
return new BaseResponse(false, "其他异常", null);
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}
}

View File

@ -0,0 +1,53 @@
package com.xncoding.jwt.api;
import com.xncoding.jwt.api.model.BaseResponse;
import com.xncoding.jwt.api.model.LoginParam;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
/**
* 登录接口类
*/
@Api(value = "登录请求接口类", tags = "登录", description = "用户请求登录获取Token")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "请求已完成"),
@ApiResponse(code = 201, message = "资源成功被创建"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 403, message = "服务器接受请求,但是拒绝处理"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器出现异常")}
)
@RestController
public class LoginController {
private static final Logger _logger = LoggerFactory.getLogger(LoginController.class);
@ApiOperation(value = "登录认证接口", notes = "不管是接口还是WebSocket连接都需要先调用此接口拿到Token然后再通过Token调用相应接口最好使用HTTPS协议。调用RESTful API方式不需要传后面两个参数如果通过WebSocket连接需要传递", produces = "application/json")
@PostMapping("/login")
public BaseResponse<String> login(@RequestHeader(name="Content-Type", defaultValue = "application/json") String contentType,
@ApiParam(value = "登录参数") @RequestBody LoginParam loginParam) {
_logger.info("用户请求登录获取Token");
return new BaseResponse<>(true, "Login success", "JWT");
}
@ApiOperation(value = "推送消息登录认证接口", notes = "这里的密码是加密后的密码", produces = "application/json")
@PostMapping("/notifyLogin")
public BaseResponse<String> notifyLogin(@RequestHeader(name="Content-Type", defaultValue = "application/json") String contentType,
@ApiParam(value = "登录参数") @RequestBody LoginParam loginParam) {
_logger.info("登录用户推送请求登录获取Token");
return new BaseResponse<>(true, "Login success", "JWT");
}
@GetMapping(path = "/401")
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ApiIgnore
public BaseResponse unauthorized() {
return new BaseResponse<>(false, "Unauthorized", null);
}
}

View File

@ -0,0 +1,41 @@
package com.xncoding.jwt.api;
import com.xncoding.jwt.api.model.BaseResponse;
import com.xncoding.jwt.api.model.UnbindParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
/**
* 通知接口类
*/
@Api(value = "通知接口类", tags = "通知", description = "服务器给相应客户端推送通知")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "请求已完成"),
@ApiResponse(code = 201, message = "资源成功被创建"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 403, message = "服务器接受请求,但是拒绝处理"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器出现异常")}
)
@RestController
@RequestMapping(value = "/notify")
public class NotifyController {
private static final Logger _logger = LoggerFactory.getLogger(NotifyController.class);
@ApiOperation(value = "解绑通知接口", notes = "后台管理员解除网点绑定后需调用此接口通知相应的POS机", produces = "application/json")
@PostMapping("/unbind")
public BaseResponse unbind(@RequestHeader(name = "Content-Type", defaultValue = "application/json") String contentType,
@RequestHeader(name = "Authorization", defaultValue = "token") String token,
@RequestBody UnbindParam unbindParam) {
_logger.info("解绑通知接口start");
return new BaseResponse<>(true, "解绑通知发送成功", null);
}
}

View File

@ -0,0 +1,123 @@
package com.xncoding.jwt.api;
import com.xncoding.jwt.api.model.*;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
/**
* 机具管理API接口类
*/
@Api(value = "机具管理业务接口类", tags = "机具管理", description = "机具管理业务接口类")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "请求已完成"),
@ApiResponse(code = 201, message = "资源成功被创建"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 403, message = "服务器接受请求,但是拒绝处理"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器出现异常")}
)
@RestController
@RequestMapping(value = "/api/v1")
public class PublicController {
private static final Logger _logger = LoggerFactory.getLogger(PublicController.class);
/**
* 入网绑定查询接口
*
* @return 是否入网
*/
@ApiOperation(value = "入网绑定查询接口", notes = "根据IMEI码来查询该POS机是否入网并绑定了网点<br/>每次打开APP的时候需要调用这个接口来进行检查<br/>如果入网并且绑定了网点才能打开APP否则必须调用入网或绑定网点接口成功后才能继续下一步", produces = "application/json")
@ApiImplicitParam(name = "imei", value = "IMEI码", required = true, dataType = "String", paramType = "query", defaultValue = "1234555SHA")
@RequestMapping(value = "/join", method = RequestMethod.GET)
public JoinBindResponse join(@RequestHeader(name="Accept", defaultValue = "application/json", required = false) String accept,
@RequestHeader(name="Authorization", defaultValue="token") String token,
@RequestParam("imei") String imei) {
_logger.info("入网查询接口 start....");
JoinBindResponse result = new JoinBindResponse();
result.setSuccess(true);
result.setCode(1);
result.setMsg("已入网并绑定了网点");
return result;
}
/**
* 请求入网接口
*
* @return 处理结果
*/
@ApiOperation(value = "请求入网接口", notes = "通过收集POS硬件信息请求入网另外还必须传入网点名称", produces = "application/json")
@RequestMapping(value = "/join", method = RequestMethod.POST)
public ResponseEntity<BaseResponse> doJoin(@RequestHeader(name="Content-Type", defaultValue = "application/json") String contentType,
@RequestHeader(name="Authorization", defaultValue="token") String token,
@RequestBody PosParam posParam) {
_logger.info("请求入网接口 start....");
BaseResponse result = new BaseResponse();
result.setSuccess(true);
result.setMsg("入网成功");
return new ResponseEntity<>(result, HttpStatus.CREATED);
}
/**
* 请求绑定网点接口
*
* @return 处理结果
*/
@ApiOperation(value = "请求绑定网点接口", notes = "POS机重新绑定新的网点", produces = "application/json")
@RequestMapping(value = "/bind", method = RequestMethod.POST)
public ResponseEntity<BaseResponse> doBind(@RequestHeader(name="Content-Type", defaultValue = "application/json") String contentType,
@RequestHeader(name="Authorization", defaultValue="token") String token,
@RequestBody BindParam bindParam) {
_logger.info("请求绑定网点接口 start....");
BaseResponse result = new BaseResponse();
result.setSuccess(true);
result.setMsg("绑定网点成功");
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* 报告位置接口
*
* @return 报告结果
*/
@ApiOperation(value = "报告位置接口", notes = "终端设备定时报告位置信息", produces = "application/json")
@RequestMapping(value = "/report", method = RequestMethod.POST)
public BaseResponse report(@RequestHeader(name="Content-Type", defaultValue = "application/json") String contentType,
@RequestHeader(name="Authorization", defaultValue="token") String token,
@RequestBody ReportParam param) {
_logger.info("定时报告接口 start....");
BaseResponse result = new BaseResponse();
result.setSuccess(true);
result.setMsg("心跳报告成功");
return result;
}
/**
* 版本检查接口
*
* @return 版本检查结果
*/
@ApiOperation(value = "APP版本更新检查", notes = "APP版本更新检查", produces = "application/json")
@RequestMapping(value = "/version", method = RequestMethod.POST)
public VersionResult version(@RequestHeader(name="Content-Type", defaultValue = "application/json") String contentType,
@RequestHeader(name="Authorization", defaultValue="token") String token,
@RequestBody VersionParam param) {
_logger.info("版本检查接口 start....");
VersionResult result = new VersionResult();
result.setAppName("AppName");
result.setDownloadUrl("http://www.baidu.com/");
result.setFindNew(true);
result.setPublishtime(new Date());
result.setTips("tips");
result.setVersion("v1.2");
return result;
}
}

View File

@ -0,0 +1,68 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import springfox.documentation.annotations.ApiIgnore;
/**
* API接口的基础返回类
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/7
*/
@ApiModel(value = "BaseResponse", description = "API接口的返回对象")
public class BaseResponse<T> {
/**
* 是否成功
*/
@ApiModelProperty(value = "是否成功", name = "success", example = "true", required = true)
private boolean success;
/**
* 说明
*/
@ApiModelProperty(value = "返回的详细说明", name = "msg", example = "成功")
private String msg;
/**
* 返回数据
*/
@ApiModelProperty(value = "返回的数据", name = "data")
private T data;
public BaseResponse() {
}
public BaseResponse(boolean success, String msg, T data) {
this.success = success;
this.msg = msg;
this.data = data;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

View File

@ -0,0 +1,41 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* POS绑定网点参数
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/7
*/
@ApiModel(value = "POS绑定网点参数", description = "POSPOS绑定网点请求时候需要传入的参数")
public class BindParam {
/**
* 机具IMEI码
*/
@ApiModelProperty(value = "IMEI码长度1-32位", name = "imei", dataType = "String", example = "2324DEEFAXX122", required = true)
private String imei;
/**
* 归属网点
*/
@ApiModelProperty(value = "归属网点长度1-64位", name = "location", dataType = "String", example = "昆明市公安局交通警察支队车辆管理所", required = true)
private String location;
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

View File

@ -0,0 +1,42 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 入网绑定返回
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/16
*/
@ApiModel(value = "入网绑定返回信息", description = "入网绑定的返回对象")
public class JoinBindResponse<T> extends BaseResponse<T> {
/**
* 返回码 1:已入网并绑定了网点 2:已入网但尚未绑定网点 3:未入网
*/
@ApiModelProperty(value = "返回码 1:已入网并绑定了网点 2:已入网但尚未绑定网点 3:未入网", name = "code", example = "1", required = true)
private int code;
/**
* 机具状态: 1:正常 2:故障 3:维修中(返厂) 4:已禁用(丢失) 5:已停用(回收)
*/
@ApiModelProperty(value = "机具状态 1:正常 2:故障 3:维修中(返厂) 4:已禁用(丢失) 5:已停用(回收)", name = "posState", example = "1", required = true)
private Integer posState;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Integer getPosState() {
return posState;
}
public void setPosState(Integer posState) {
this.posState = posState;
}
}

View File

@ -0,0 +1,67 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 登录认证接口参数
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/9
*/
@ApiModel(value = "登录认证接口参数", description = "登录认证接口参数")
public class LoginParam {
/**
* 用户名
*/
@ApiModelProperty(value = "用户名", name = "username", example = "admin", required = true)
private String username;
/**
* 密码
*/
@ApiModelProperty(value = "密码", name = "password", example = "123456", required = true)
private String password;
/**
* Application ID
*/
@ApiModelProperty(value = "Application ID", name = "appid", example = "com.xncoding.xzpay", required = false)
private String appid;
/**
* IMEI码
*/
@ApiModelProperty(value = "IMEI码", name = "imei", example = "TUYIUOIU234234YUII", required = false)
private String imei;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
}

View File

@ -0,0 +1,133 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* POS入网参数
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/7
*/
@ApiModel(value = "POS入网参数", description = "POS入网请求时候需要传入的参数")
public class PosParam {
/**
* 机具IMEI码
*/
@ApiModelProperty(value = "IMEI码长度1-32位", name = "imei", dataType = "String", example = "2324DEEFAXX122", required = true)
private String imei;
/**
* 序列号(SN)
*/
@ApiModelProperty(value = "序列号SN长度1-64位", name = "sn", dataType = "String", example = "ssssssnnnn", required = true)
private String sn;
/**
* 机具型号
*/
@ApiModelProperty(value = "机具型号长度1-32位", name = "series", dataType = "String", example = "APOS A8", required = true)
private String series;
/**
* Android版本
*/
@ApiModelProperty(value = "Android版本长度1-32位", name = "androidVersion", dataType = "String", example = "6.2.0", required = true)
private String androidVersion;
/**
* 版本号
*/
@ApiModelProperty(value = "版本号长度1-32位", name = "version", dataType = "String", example = "B0182_C2BOM_V1.1.4_20171213/4.0.28", required = true)
private String version;
/**
* 归属网点
*/
@ApiModelProperty(value = "归属网点长度1-64位", name = "location", dataType = "String", example = "昆明市公安局交通警察支队车辆管理所", required = true)
private String location;
/**
* 产权方
*/
@ApiModelProperty(value = "机具产权方长度1-64位", name = "owner", dataType = "String", example = "招商银行昆明分行", required = true)
private String owner;
/**
* 备注
*/
@ApiModelProperty(value = "备注说明长度0-255位", name = "tips", dataType = "String", example = "备注说明")
private String tips;
/**
* 应用ID
*/
@ApiModelProperty(value = "APP应用ID长度1-64位每个APP都有唯一的Application Id并且这个应用ID必须已经存在于系统之中",
name = "applicationId", dataType = "String", example = "com.xncoding.xzpay", required = true)
private String applicationId;
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getSeries() {
return series;
}
public void setSeries(String series) {
this.series = series;
}
public String getAndroidVersion() {
return androidVersion;
}
public void setAndroidVersion(String androidVersion) {
this.androidVersion = androidVersion;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getTips() {
return tips;
}
public void setTips(String tips) {
this.tips = tips;
}
public String getApplicationId() {
return applicationId;
}
public void setApplicationId(String applicationId) {
this.applicationId = applicationId;
}
}

View File

@ -0,0 +1,41 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 报告参数
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/7
*/
@ApiModel(value = "报告参数", description = "报告参数")
public class ReportParam {
/**
* IMEI码
*/
@ApiModelProperty(value = "IMEI码长度1-32位", name = "imei", example = "2324DEEFAXX122", required = true)
private String imei;
/**
* 位置
*/
@ApiModelProperty(value = "位置长度1-255位", name = "location", example = "广东省广州市天河区五山路321号", required = true)
private String location;
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

View File

@ -0,0 +1,41 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 解绑通知参数
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/9
*/
@ApiModel(value = "解绑通知参数", description = "解绑通知参数")
public class UnbindParam {
/**
* IMEI码
*/
@ApiModelProperty(value = "IMEI码", name = "imei", example = "TUYIUOIU234234YUII")
private String imei;
/**
* 网点
*/
@ApiModelProperty(value = "网点", name = "location", example = "广州市天河区交警7区")
private String location;
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

View File

@ -0,0 +1,54 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* APP版本检查接口参数
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/9
*/
@ApiModel(value = "APP版本检查参数", description = "APP版本检查参数")
public class VersionParam {
/**
* 机具IMEI码
*/
@ApiModelProperty(value = "IMEI码", name = "imei", example = "2324DEEFAXX122", required = true)
private String imei;
/**
* 应用ID
*/
@ApiModelProperty(value = "APP应用ID每个APP都有唯一的Application Id", name = "applicationId", example = "com.xncoding.xzpay", required = true)
private String applicationId;
/**
* 当前版本号
*/
@ApiModelProperty(value = "APP的当前版本号", name = "version", example = "1.2.0", required = true)
private String version;
public String getApplicationId() {
return applicationId;
}
public void setApplicationId(String applicationId) {
this.applicationId = applicationId;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
}

View File

@ -0,0 +1,96 @@
package com.xncoding.jwt.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
/**
* 版本检查结果
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/9
*/
@ApiModel(value = "APP版本检查结果", description = "APP版本检查结果")
public class VersionResult {
/**
* 是否发现新版本
*/
@ApiModelProperty(value = "是否发现新版本(true:发现新版本false:没有发现新版本)", name = "findNew", example = "true", required = true)
private boolean findNew;
/**
* APP名称
*/
@ApiModelProperty(value = "APP名称", name = "appName", example = "行政收费")
private String appName;
/**
* 新版本号
*/
@ApiModelProperty(value = "新版本号", name = "version", example = "v1.3.8")
private String version;
/**
* 新版本说明
*/
@ApiModelProperty(value = "新版本说明", name = "tips", example = "增加人脸识别功能")
private String tips;
/**
* 新版本发布时间
*/
@ApiModelProperty(value = "新版本发布时间", name = "publishtime", example = "2017-12-24 12:32:19")
private Date publishtime;
/**
* 新版本下载地址
*/
@ApiModelProperty(value = "新版本下载地址", name = "downloadUrl", example = "http://xncoding.net/files/行政收费_1.3.0.apk")
private String downloadUrl;
public boolean isFindNew() {
return findNew;
}
public void setFindNew(boolean findNew) {
this.findNew = findNew;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getTips() {
return tips;
}
public void setTips(String tips) {
this.tips = tips;
}
public Date getPublishtime() {
return publishtime;
}
public void setPublishtime(Date publishtime) {
this.publishtime = publishtime;
}
}

View File

@ -0,0 +1,55 @@
package com.xncoding.jwt.config;
import com.google.common.collect.Sets;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger2的Java配置类
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/7
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.produces(Sets.newHashSet("application/json"))
.consumes(Sets.newHashSet("application/json"))
.protocols(Sets.newHashSet("http", "https"))
.apiInfo(apiInfo())
.forCodeGeneration(true)
.select()
// 指定controller存放的目录路径
.apis(RequestHandlerSelectors.basePackage("com.xncoding.jwt.api"))
// .paths(PathSelectors.ant("/api/v1/*"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 文档标题
.title("系统API服务")
// 文档描述
.description("系统API接口文档")
// .termsOfServiceUrl("https://github.com/yidao620c")
.version("v1")
// .license("MIT 协议")
// .licenseUrl("http://www.opensource.org/licenses/MIT")
// .contact(new Contact("熊能","https://github.com/yidao620c","yidao620@gmail.com"))
.build();
}
}

View File

@ -0,0 +1,97 @@
##########################################################
################## 所有profile共有的配置 #################
##########################################################
################### 自定义项目配置 ###################
xncoding:
socket-port: 9096 #socket端口
ping-interval: 60000 #Ping消息间隔毫秒
ping-timeout: 180000 #Ping消息超时时间毫秒
################### 项目启动端口 ###################
server.port: 9095
################### spring配置 ###################
spring:
profiles:
active: dev
http:
multipart:
max-request-size: 100MB #最大请求大小
max-file-size: 100MB #最大文件大小
################### mybatis-plus配置 ###################
mybatis-plus:
mapper-locations: classpath*:com/xncoding/jwt/dao/repository/mapping/*.xml
typeAliasesPackage: >
com.xncoding.jwt.api.model,
com.xncoding.jwt.dao.entity,
com.xncoding.jwt.common.dao.entity
global-config:
id-type: 0 # 0:数据库ID自增 1:用户输入id 2:全局唯一id(IdWorker) 3:全局唯一ID(uuid)
db-column-underline: false
refresh-mapper: true
configuration:
map-underscore-to-camel-case: true
cache-enabled: true #配置的缓存的全局开关
lazyLoadingEnabled: true #延时加载的开关
multipleResultSetsEnabled: true #开启的话,延时加载一个属性时会加载该对象全部属性,否则按需加载属性
################### spring security配置 ###################
security:
ignored: /static/**
logging:
level:
org.springframework.web.servlet: ERROR
---
#####################################################################
######################## 开发环境profile ##########################
#####################################################################
spring:
profiles: dev
datasource:
url: jdbc:mysql://123.207.66.156:3306/pos?useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8
username: root
password: ******
thymeleaf:
cache: false
################### 自定义项目配置 ###################
xncoding:
apk-url-prefix: http://xncoding.net/files/ #APK文件访问URL前缀
logging:
level:
ROOT: INFO
com:
xncoding: DEBUG
file: E:/logs/pos-api.log
---
#####################################################################
######################## 测试环境profile ##########################
#####################################################################
spring:
profiles: test
datasource:
url: jdbc:mysql://123.207.66.156:3306/pos?useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8
username: root
password: ******
thymeleaf:
cache: false
################### 自定义项目配置 ###################
xncoding:
apk-url-prefix: https://show.xncoding.net/files/ #APK文件访问URL前缀
logging:
level:
ROOT: INFO
com:
xncoding: DEBUG
file: /var/logs/app-manage-api.log

View File

@ -0,0 +1,15 @@
package com.xncoding.jwt;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* 测试密码加密
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
}

View File

@ -0,0 +1,112 @@
package com.xncoding.jwt;
import io.github.swagger2markup.GroupBy;
import io.github.swagger2markup.Language;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import java.io.BufferedWriter;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Swagger2MarkupTest
*
* @author XiongNeng
* @version 1.0
* @since 2018/1/26
*/
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class Swagger2MarkupTest {
@Autowired
private MockMvc mockMvc;
private static final Logger LOG = LoggerFactory.getLogger(Swagger2MarkupTest.class);
/**
* 自动生成adoc文件
* @throws Exception e
*
* 执行完成后生成PDF文件方法
*
* 首先在`build/swagger.adoc`的顶部加入
```
:toclevels: 3
:numbered:
```
注意有个空行分割目的是左边导航菜单是3级并且自动加序号
为了美化显示还要将`swagger.adoc`中全局替换一下
```
cols=".^2,.^3,.^9,.^4,.^2"
```
替换成
```
cols=".^2,.^3,.^6,.^4,.^5"
```
然后在/resources目录下面执行
```
asciidoctor-pdf -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-style=KaiGenGothicCN swagger/swagger.adoc
```
会在`swagger.adoc`的同级目录生成`swagger.pdf`文件
*/
@Test
public void createSpringFoxSwaggerJson() throws Exception {
// String outputDir = System.getProperty("swaggerOutputDir"); // mvn test
MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
String swaggerJson = response.getContentAsString();
// Files.createDirectories(Paths.get(outputDir));
// try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputDir, "swagger.json"), StandardCharsets.UTF_8)){
// writer.write(swaggerJson);
// }
LOG.info("--------------------swaggerJson create --------------------");
convertAsciidoc(swaggerJson);
LOG.info("--------------------swagon.json to asciiDoc finished --------------------");
}
/**
* 将swagger.yaml或swagger.json转换成漂亮的 AsciiDoc
* 访问http://localhost:9095/v2/api-docs
* 将页面结果保存为src/main/resources/swagger.json
*/
private void convertAsciidoc(String swaggerStr) {
// Path localSwaggerFile = Paths.get(System.getProperty("swaggerOutputDir"), "swagger.json");
Path outputFile = Paths.get(System.getProperty("asciiDocOutputDir"));
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.ASCIIDOC)
.withOutputLanguage(Language.ZH)
.withPathsGroupedBy(GroupBy.TAGS)
.withGeneratedExamples()
.withoutInlineSchema()
.build();
Swagger2MarkupConverter converter = Swagger2MarkupConverter.from(swaggerStr)
.withConfig(config)
.build();
converter.toFile(outputFile);
}
}

Binary file not shown.