diff --git a/springboot-resttemplate/.gitignore b/springboot-resttemplate/.gitignore new file mode 100644 index 0000000..1e3c5bb --- /dev/null +++ b/springboot-resttemplate/.gitignore @@ -0,0 +1,14 @@ +# 此为注释– 将被Git 忽略 +# /结尾表示是目录,忽略目录和目录下的所有件 +# /开头表示根目录,否则是.gitignore的相对目录 +# !开头表示反选 +.idea/ +target/ +*.iml +*.ipr +*.iws +*.log +.svn/ +.project +rebel.xml +.rebel-remote.xml.* diff --git a/springboot-resttemplate/LICENSE b/springboot-resttemplate/LICENSE new file mode 100644 index 0000000..83cd47d --- /dev/null +++ b/springboot-resttemplate/LICENSE @@ -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. diff --git a/springboot-resttemplate/README.md b/springboot-resttemplate/README.md new file mode 100644 index 0000000..80d3308 --- /dev/null +++ b/springboot-resttemplate/README.md @@ -0,0 +1,13 @@ +## 使用RestTemplate + +使用RestTemplate访问RESTful API接口 + +## 测试用例 + +`com.xncoding.pos.ApplicationTests.java` + +## 许可证 + +Copyright (c) 2018 Xiong Neng + +基于 MIT 协议发布: diff --git a/springboot-resttemplate/pom.xml b/springboot-resttemplate/pom.xml new file mode 100644 index 0000000..a398cc4 --- /dev/null +++ b/springboot-resttemplate/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + + com.xncoding + springboot-resttemplate + 1.0.0-SNAPSHOT + jar + + springboot-resttemplate + 使用RestTemplate访问RESTful API接口 + + + org.springframework.boot + spring-boot-starter-parent + 1.5.9.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-jetty + + + org.apache.httpcomponents + httpclient + 4.3.6 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.hamcrest + hamcrest-core + 1.3 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20 + + true + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + src/main/resources + + + src/main/java + + **/*.xml + + + + + + \ No newline at end of file diff --git a/springboot-resttemplate/run.sh b/springboot-resttemplate/run.sh new file mode 100644 index 0000000..955efb1 --- /dev/null +++ b/springboot-resttemplate/run.sh @@ -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 diff --git a/springboot-resttemplate/src/main/java/com/xncoding/pos/Application.java b/springboot-resttemplate/src/main/java/com/xncoding/pos/Application.java new file mode 100644 index 0000000..adc4c48 --- /dev/null +++ b/springboot-resttemplate/src/main/java/com/xncoding/pos/Application.java @@ -0,0 +1,12 @@ +package com.xncoding.pos; + +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); + } + +} diff --git a/springboot-resttemplate/src/main/java/com/xncoding/pos/config/RestClientConfig.java b/springboot-resttemplate/src/main/java/com/xncoding/pos/config/RestClientConfig.java new file mode 100644 index 0000000..5606245 --- /dev/null +++ b/springboot-resttemplate/src/main/java/com/xncoding/pos/config/RestClientConfig.java @@ -0,0 +1,59 @@ +package com.xncoding.pos.config; + +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** + * RestTemplate客户端连接池配置 + * + * @author XiongNeng + * @version 1.0 + * @since 2018/1/24 + */ +@Configuration +public class RestClientConfig { + @Bean + public ClientHttpRequestFactory httpRequestFactory() { + return new HttpComponentsClientHttpRequestFactory(httpClient()); + } + + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder) { + return new RestTemplate(httpRequestFactory()); + } + + @Bean + public HttpClient httpClient() { + Registry registry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", SSLConnectionSocketFactory.getSocketFactory()) + .build(); + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); + connectionManager.setMaxTotal(5); + connectionManager.setDefaultMaxPerRoute(5); + + RequestConfig requestConfig = RequestConfig.custom() + .setSocketTimeout(8000) + .setConnectTimeout(8000) + .setConnectionRequestTimeout(8000) + .build(); + + return HttpClientBuilder.create() + .setDefaultRequestConfig(requestConfig) + .setConnectionManager(connectionManager) + .build(); + } +} diff --git a/springboot-resttemplate/src/main/java/com/xncoding/pos/controller/LoginController.java b/springboot-resttemplate/src/main/java/com/xncoding/pos/controller/LoginController.java new file mode 100644 index 0000000..7ec4e60 --- /dev/null +++ b/springboot-resttemplate/src/main/java/com/xncoding/pos/controller/LoginController.java @@ -0,0 +1,40 @@ +package com.xncoding.pos.controller; + +import com.xncoding.pos.model.LoginParam; +import com.xncoding.pos.model.UnbindParam; +import com.xncoding.pos.model.BaseResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +/** + * 登录接口类 + */ +@RestController +public class LoginController { + + private static final Logger _logger = LoggerFactory.getLogger(LoginController.class); + + @PostMapping("/login") + public BaseResponse login(@RequestHeader(name = "Content-Type", defaultValue = "application/json") String contentType, + @RequestBody LoginParam loginParam) { + _logger.info("用户请求登录获取Token"); + String username = loginParam.getUsername(); + String password = loginParam.getPassword(); + return new BaseResponse<>(true, "Login success", username + password); + } + + @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"); + String imei = unbindParam.getImei(); + String location = unbindParam.getLocation(); + return new BaseResponse<>(true, "解绑通知发送成功", "unbind"); + } + +} diff --git a/springboot-resttemplate/src/main/java/com/xncoding/pos/model/BaseResponse.java b/springboot-resttemplate/src/main/java/com/xncoding/pos/model/BaseResponse.java new file mode 100644 index 0000000..b7c3e5e --- /dev/null +++ b/springboot-resttemplate/src/main/java/com/xncoding/pos/model/BaseResponse.java @@ -0,0 +1,60 @@ +package com.xncoding.pos.model; + +/** + * Controller的基础返回类 + * + * @author XiongNeng + * @version 1.0 + * @since 2018/1/7 + */ +public class BaseResponse { + /** + * 是否成功 + */ + private boolean success; + + /** + * 说明 + */ + private String msg; + + /** + * 返回数据 + */ + 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; + } + +} diff --git a/springboot-resttemplate/src/main/java/com/xncoding/pos/model/LoginParam.java b/springboot-resttemplate/src/main/java/com/xncoding/pos/model/LoginParam.java new file mode 100644 index 0000000..466e8e3 --- /dev/null +++ b/springboot-resttemplate/src/main/java/com/xncoding/pos/model/LoginParam.java @@ -0,0 +1,59 @@ +package com.xncoding.pos.model; + +/** + * 登录认证接口参数 + * + * @author XiongNeng + * @version 1.0 + * @since 2018/1/9 + */ +public class LoginParam { + /** + * 用户名 + */ + private String username; + /** + * 密码 + */ + private String password; + /** + * Application ID + */ + private String appid; + /** + * IMEI码 + */ + 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; + } +} diff --git a/springboot-resttemplate/src/main/java/com/xncoding/pos/model/UnbindParam.java b/springboot-resttemplate/src/main/java/com/xncoding/pos/model/UnbindParam.java new file mode 100644 index 0000000..c8f5737 --- /dev/null +++ b/springboot-resttemplate/src/main/java/com/xncoding/pos/model/UnbindParam.java @@ -0,0 +1,35 @@ +package com.xncoding.pos.model; + +/** + * 解绑通知参数 + * + * @author XiongNeng + * @version 1.0 + * @since 2018/1/9 + */ +public class UnbindParam { + /** + * IMEI码 + */ + private String imei; + /** + * 网点 + */ + 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; + } +} diff --git a/springboot-resttemplate/src/main/resources/application.yml b/springboot-resttemplate/src/main/resources/application.yml new file mode 100644 index 0000000..ea74468 --- /dev/null +++ b/springboot-resttemplate/src/main/resources/application.yml @@ -0,0 +1,46 @@ +########################################################## +################## 所有profile共有的配置 ################# +########################################################## + +################### 项目启动端口 ################### +server.port: 8092 + +################### spring配置 ################### +spring: + profiles: + active: dev + +logging: + level: + org.springframework.web.servlet: ERROR + +--- + +##################################################################### +######################## 开发环境profile ########################## +##################################################################### +spring: + profiles: dev + +logging: + level: + ROOT: INFO + com: + xncoding: DEBUG + file: E:/logs/app.log + +--- + +##################################################################### +######################## 测试环境profile ########################## +##################################################################### + +spring: + profiles: test + +logging: + level: + ROOT: INFO + com: + xncoding: DEBUG + file: /var/logs/app.log diff --git a/springboot-resttemplate/src/main/resources/banner.txt b/springboot-resttemplate/src/main/resources/banner.txt new file mode 100644 index 0000000..859b78f --- /dev/null +++ b/springboot-resttemplate/src/main/resources/banner.txt @@ -0,0 +1,23 @@ + + _____ _______ _____ _____ + /\ \ /::\ \ /\ \ /\ \ + /::\____\ /::::\ \ /::\____\ /::\ \ + /:::/ / /::::::\ \ /:::/ / /::::\ \ + /:::/ / /::::::::\ \ /:::/ / /::::::\ \ + /:::/ / /:::/~~\:::\ \ /:::/ / /:::/\:::\ \ + /:::/ / /:::/ \:::\ \ /:::/____/ /:::/__\:::\ \ + /:::/ / /:::/ / \:::\ \ |::| | /::::\ \:::\ \ + /:::/ / /:::/____/ \:::\____\ |::| | _____ /::::::\ \:::\ \ + /:::/ / |:::| | |:::| | |::| | /\ \ /:::/\:::\ \:::\ \ +/:::/____/ |:::|____| |:::| | |::| | /::\____\/:::/__\:::\ \:::\____\ +\:::\ \ \:::\ \ /:::/ / |::| | /:::/ /\:::\ \:::\ \::/ / + \:::\ \ \:::\ \ /:::/ / |::| | /:::/ / \:::\ \:::\ \/____/ + \:::\ \ \:::\ /:::/ / |::|____|/:::/ / \:::\ \:::\ \ + \:::\ \ \:::\__/:::/ / |:::::::::::/ / \:::\ \:::\____\ + \:::\ \ \::::::::/ / \::::::::::/____/ \:::\ \::/ / + \:::\ \ \::::::/ / ~~~~~~~~~~ \:::\ \/____/ + \:::\ \ \::::/ / \:::\ \ + \:::\____\ \::/____/ \:::\____\ + \::/ / ~~ \::/ / + \/____/ \/____/ + diff --git a/springboot-resttemplate/src/test/java/com/xncoding/pos/ApplicationTests.java b/springboot-resttemplate/src/test/java/com/xncoding/pos/ApplicationTests.java new file mode 100644 index 0000000..7c1a7c4 --- /dev/null +++ b/springboot-resttemplate/src/test/java/com/xncoding/pos/ApplicationTests.java @@ -0,0 +1,75 @@ +package com.xncoding.pos; + +import com.xncoding.pos.model.LoginParam; +import com.xncoding.pos.model.UnbindParam; +import com.xncoding.pos.model.BaseResponse; +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.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import java.net.URI; +import java.net.URISyntaxException; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * 测试任务 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ApplicationTests { + private static final Logger logger = LoggerFactory.getLogger(ApplicationTests.class); + /** + * @LocalServerPort 提供了 @Value("${local.server.port}") 的代替 + */ + @LocalServerPort + private int port; + @Autowired + private RestTemplate restTemplate; + + @Test + public void testRestTemplate() { + logger.info("解绑成功后推送消息给对应的POS机"); + LoginParam param = new LoginParam(); + param.setUsername("admin"); + param.setPassword("12345678"); + String loginUrl = String.format("http://localhost:%d/login", port); + BaseResponse r = restTemplate.postForObject(loginUrl, param, BaseResponse.class); + assertThat(r.isSuccess(), is(true)); + + logger.info("推送消息登录认证成功"); + String token = (String) r.getData(); + UnbindParam unbindParam = new UnbindParam(); + unbindParam.setImei("imei"); + unbindParam.setLocation("location"); + // 设置HTTP Header信息 + String unbindUrl = String.format("http://localhost:%d/unbind", port); + URI uri; + try { + uri = new URI(unbindUrl); + } catch (URISyntaxException e) { + logger.error("URI构建失败", e); + throw new RuntimeException("URI构建失败"); + } + RequestEntity requestEntity = RequestEntity + .post(uri) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .header("Authorization", token) + .body(unbindParam); + ResponseEntity responseEntity = restTemplate.exchange(requestEntity, BaseResponse.class); + BaseResponse r2 = responseEntity.getBody(); + assertThat(r2.isSuccess(), is(true)); + assertThat(r2.getData(), is("unbind")); + } +}