├── src ├── main │ ├── resources │ │ ├── keystores │ │ │ ├── kserver.keystore │ │ │ └── tserver.keystore │ │ ├── config │ │ │ ├── application.yaml │ │ │ ├── application-dev.yaml │ │ │ ├── application-pro.yaml │ │ │ └── application-test.yaml │ │ └── logback-spring.xml │ └── java │ │ └── com │ │ └── lance │ │ ├── api │ │ ├── common │ │ │ ├── constant │ │ │ │ ├── Globals.java │ │ │ │ ├── ServerCode.java │ │ │ │ └── ResponseCode.java │ │ │ ├── exception │ │ │ │ └── BaseException.java │ │ │ ├── core │ │ │ │ └── annotation │ │ │ │ │ ├── Validation.java │ │ │ │ │ └── impl │ │ │ │ │ └── ValidationUtils.java │ │ │ ├── config │ │ │ │ ├── ExecutorConfig.java │ │ │ │ └── DruidConfig.java │ │ │ ├── base │ │ │ │ ├── model │ │ │ │ │ ├── Communication.java │ │ │ │ │ └── JsonResult.java │ │ │ │ └── dao │ │ │ │ │ └── BaseDao.java │ │ │ └── util │ │ │ │ ├── SpringContextUtil.java │ │ │ │ └── SftpUtil.java │ │ └── business │ │ │ ├── dao │ │ │ ├── ApiDao.java │ │ │ └── SysDao.java │ │ │ ├── pojo │ │ │ ├── model │ │ │ │ ├── FieldNameModel.java │ │ │ │ ├── ReturnModel.java │ │ │ │ ├── EntryModel.java │ │ │ │ ├── EntryBodyModel.java │ │ │ │ └── EntryHeadModel.java │ │ │ └── dto │ │ │ │ └── SampleModel.java │ │ │ ├── service │ │ │ ├── wrap │ │ │ │ ├── core │ │ │ │ │ ├── SameServiceWrapper.java │ │ │ │ │ ├── BaseServiceWrapper.java │ │ │ │ │ └── ServiceWrapperContainer.java │ │ │ │ ├── config │ │ │ │ │ └── InitServiceWrapper.java │ │ │ │ └── business │ │ │ │ │ ├── CheckWrapper.java │ │ │ │ │ ├── SaveWrapper.java │ │ │ │ │ └── InquiryWrapper.java │ │ │ ├── ApiService.java │ │ │ └── impl │ │ │ │ └── ApiServiceImpl.java │ │ │ ├── socketserver │ │ │ ├── netty │ │ │ │ ├── MessageEncoder.java │ │ │ │ ├── MessageDecoder.java │ │ │ │ ├── ServerHandler.java │ │ │ │ └── NettyServer.java │ │ │ └── nativesocket │ │ │ │ └── ServerSocket.java │ │ │ └── util │ │ │ ├── ComposeUtil.java │ │ │ ├── DealSocket.java │ │ │ └── ByteDataBuffer.java │ │ └── Application.java └── test │ └── java │ └── com │ ├── sslsocketclient │ ├── res │ │ ├── kclient.keystore │ │ └── tclient.keystore │ ├── 查询.java │ ├── HexStringUtils.java │ ├── ComposeDemo.java │ ├── DeSplitDemo.java │ └── ByteDataBuffer.java │ └── lance │ ├── BaseTests.java │ └── ApplicationTests.java ├── README.md └── pom.xml /src/main/resources/keystores/kserver.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lance2038/springbootNettySslSocketDemo/HEAD/src/main/resources/keystores/kserver.keystore -------------------------------------------------------------------------------- /src/main/resources/keystores/tserver.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lance2038/springbootNettySslSocketDemo/HEAD/src/main/resources/keystores/tserver.keystore -------------------------------------------------------------------------------- /src/test/java/com/sslsocketclient/res/kclient.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lance2038/springbootNettySslSocketDemo/HEAD/src/test/java/com/sslsocketclient/res/kclient.keystore -------------------------------------------------------------------------------- /src/test/java/com/sslsocketclient/res/tclient.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lance2038/springbootNettySslSocketDemo/HEAD/src/test/java/com/sslsocketclient/res/tclient.keystore -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/constant/Globals.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.constant; 2 | 3 | 4 | /** 5 | * 全局静态变量类 6 | */ 7 | public class Globals 8 | { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/exception/BaseException.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.exception; 2 | 3 | /** 4 | * 异常处理类的基类 5 | */ 6 | public class BaseException extends RuntimeException 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/com/lance/BaseTests.java: -------------------------------------------------------------------------------- 1 | package com.lance; 2 | 3 | import org.junit.Test; 4 | 5 | public class BaseTests 6 | { 7 | @Test 8 | public void test() 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/dao/ApiDao.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.dao; 2 | 3 | 4 | import com.lance.api.common.base.dao.BaseDao; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | *

业务处理dao层 9 | * 10 | * @author lance 11 | * @since 2018-09-25 12 | **/ 13 | @Repository 14 | public class ApiDao extends BaseDao 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/lance/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.lance; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ApplicationTests 11 | { 12 | @Test 13 | public void contextLoads() 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/pojo/model/FieldNameModel.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.pojo.model; 2 | 3 | /** 4 | * 返回信息model 5 | * 6 | * @author lance 7 | * @since 2018-10-17 8 | */ 9 | public interface FieldNameModel 10 | { 11 | /** 12 | * 记录数 13 | */ 14 | public static String RECORD_COUNT = "recordCount"; 15 | /** 16 | * 金额 17 | */ 18 | public static String RECORD_AMT = "recordAmt"; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/config/application.yaml: -------------------------------------------------------------------------------- 1 | # spring config 2 | spring: 3 | profiles: 4 | active: dev 5 | main: 6 | banner-mode: console 7 | output: 8 | ansi: 9 | enabled: detect 10 | #set response encoding 11 | http: 12 | encoding: 13 | force: true 14 | # logging config 15 | logging: 16 | register-shutdown-hook: true 17 | # thread Pool 18 | executor: 19 | corePoolSize: 10 20 | maxPoolSize: 200 21 | queueCapacity: 10 22 | namePrefix: AsyncExecutor- 23 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/constant/ServerCode.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.constant; 2 | 3 | /** 4 | * 业务编码 5 | */ 6 | public class ServerCode 7 | { 8 | /** 9 | * 查询 10 | */ 11 | public static final String SERVER_CODE_QUERY = "200001"; 12 | 13 | /** 14 | * 保存 15 | */ 16 | public static final String SERVER_CODE_SAVE = "200002"; 17 | 18 | /** 19 | * 校验 20 | */ 21 | public static final String SERVER_CODE_CHECK = "200011"; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/pojo/model/ReturnModel.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.pojo.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.experimental.Accessors; 7 | 8 | import java.util.Map; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @Accessors(chain = true) 14 | public class ReturnModel 15 | { 16 | private String servCode; 17 | private String msgId; 18 | private Map map; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/pojo/dto/SampleModel.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.pojo.dto; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.math.BigDecimal; 9 | 10 | /** 11 | * @author lance 12 | * @since 2018-09-25 13 | **/ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class SampleModel 18 | { 19 | /** 20 | * 总数 21 | */ 22 | public int count; 23 | /** 24 | * 总额 25 | */ 26 | public BigDecimal amt; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/pojo/model/EntryModel.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.pojo.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | 8 | /** 9 | * @author lance 10 | * @version v0.0.1 11 | * @describe 接收报文 12 | * @since 2018/10/11 13 | **/ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class EntryModel 18 | { 19 | private String head; 20 | private String body; 21 | private EntryHeadModel headModel; 22 | private EntryBodyModel bodyModel; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/wrap/core/SameServiceWrapper.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.wrap.core; 2 | 3 | 4 | import com.lance.api.business.pojo.model.EntryModel; 5 | 6 | /** 7 | * 判断多个业务是否有相同的servCode,若存在相同情况需继承此类重写此方法,改为return true 8 | * 9 | * @author lance 10 | * @since 2018-10-15 11 | */ 12 | public class SameServiceWrapper 13 | { 14 | 15 | /** 16 | * 判断是否存在servCode相同的情况 17 | * 18 | * @return 19 | */ 20 | public Boolean hasSameService() 21 | { 22 | return false; 23 | } 24 | 25 | 26 | public boolean sameIsMyDo(EntryModel entryModel) 27 | { 28 | return false; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/core/annotation/Validation.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.core.annotation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.Target; 5 | 6 | import static java.lang.annotation.ElementType.FIELD; 7 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 8 | 9 | @Target({FIELD}) 10 | @Retention(RUNTIME) 11 | public @interface Validation 12 | { 13 | // 允许的值 14 | String[] allowValue() default {}; 15 | 16 | // 限制的值 17 | String[] limitValue() default {}; 18 | 19 | // 必须为空 20 | boolean mustEmpty() default false; 21 | 22 | // 若值为限制值的返回信息 23 | String limitMsg() default "校验未通过"; 24 | 25 | } -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/ApiService.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service; 2 | 3 | 4 | import com.lance.api.common.base.model.JsonResult; 5 | 6 | /** 7 | *

业务处理service接口 8 | * 9 | * @author lance 10 | * @since 2018-10-15 11 | **/ 12 | public interface ApiService 13 | { 14 | /** 15 | * 获取信息 16 | * 17 | * @param key 标识符 18 | * @return 查询结果 19 | * @throws Exception 20 | */ 21 | JsonResult queryInfo(String key) throws Exception; 22 | 23 | 24 | /** 25 | * 保存信息 26 | * 27 | * @param key 标识 28 | * @param msg 信息 29 | * @return 存储结果 30 | * @throws Exception 31 | */ 32 | JsonResult saveData(String key, String msg) throws Exception; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/dao/SysDao.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.dao; 2 | 3 | import com.lance.api.common.base.dao.BaseDao; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public class SysDao extends BaseDao 8 | { 9 | /** 10 | * 获取当前系统时间 11 | * 12 | * @return 13 | */ 14 | public String getDBCurrentTime() 15 | { 16 | String sql = "select to_char(sysdate,'yyyy-MM-dd hh24:mi:ss') from dual"; 17 | return queryForString(sql); 18 | } 19 | 20 | /** 21 | * 获取当前系统日期 22 | * 23 | * @return 24 | */ 25 | public String getDBCurrentDate() 26 | { 27 | String sql = "select to_char(sysdate,'yyyy-MM-dd') from dual"; 28 | return queryForString(sql); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/pojo/model/EntryBodyModel.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.pojo.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | 8 | /** 9 | * @author lance 10 | * @version v0.0.1 11 | * @describe 接收报文-包体:是报文数据主体内容,承载了报文的业务数据,具体每个报文包含了哪些业务数据将在具体的业务接口中详细描述 12 | * @since 2018/10/11 13 | **/ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class EntryBodyModel 18 | { 19 | /** 20 | * 查询条件的类别 21 | */ 22 | private String queryType; 23 | /** 24 | * 对应查询类别的查询条件。 25 | */ 26 | private String queryValue; 27 | /** 28 | * 唯一标识 29 | */ 30 | private String key; 31 | /** 32 | * 预留 33 | */ 34 | private String extend; 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/pojo/model/EntryHeadModel.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.pojo.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | 8 | /** 9 | * @author lance 10 | * @version v0.0.1 11 | * @describe 接收报文--包头:是报文数据头信息,记录了一系列约定数据 12 | * @since 2018/10/11 13 | **/ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class EntryHeadModel 18 | { 19 | /** 20 | * 报文id 21 | */ 22 | private String msgId; 23 | /** 24 | * 报文的发送时间,时间格式为 yyyyMMddHH24miss 25 | */ 26 | private String msgTime; 27 | /** 28 | * 服务编号。详见各个接口 29 | */ 30 | private String servCode; 31 | /** 32 | * 报文的版本号 33 | */ 34 | private String version; 35 | /** 36 | * 预留字段 37 | */ 38 | private String extend; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/wrap/core/BaseServiceWrapper.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.wrap.core; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | *

包装类基类 7 | * 8 | * @author lance 9 | * @since 2018-10-15 10 | */ 11 | public abstract class BaseServiceWrapper extends SameServiceWrapper 12 | { 13 | /** 14 | * 获取当前servCode 15 | * 16 | * @return 17 | */ 18 | public abstract String doCode(); 19 | 20 | /** 21 | * 传入的servCode是否为当前包装类的servCode 22 | * 23 | * @param doCode 24 | * @return 25 | */ 26 | public Boolean isMyDo(String doCode) 27 | { 28 | return doCode.equals(doCode()); 29 | } 30 | 31 | /** 32 | * 处理业务 33 | * 34 | * @param params 35 | * @return 36 | * @throws Exception 37 | */ 38 | public abstract Map handle(Object... params) throws Exception; 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # socket/sslSocket + Netty/原生socket 整合的Demo,可任意切换 2 | # CSDN地址:https://blog.csdn.net/sinat_30637097/article/details/87971873 3 | **关于项目中使用的4个证书,使用Java自带的keytool命令,在命令行生成:** 4 | _1、生成服务器端私钥kserver.keystore文件_ 5 | `keytool -genkey -alias serverkey -validity 1 -keystore kserver.keystore` 6 | _2、根据私钥,导出服务器端安全证书_ 7 | `keytool -export -alias serverkey -keystore kserver.keystore -file server.crt` 8 | _3、将服务器端证书,导入到客户端的Trust KeyStore中_ 9 | `keytool -import -alias serverkey -file server.crt -keystore tclient.keystore` 10 | _4、生成客户端私钥kclient.keystore文件_ 11 | `keytool -genkey -alias clientkey -validity 1 -keystore kclient.keystore` 12 | _5、根据私钥,导出客户端安全证书_ 13 | `keytool -export -alias clientkey -keystore kclient.keystore -file client.crt` 14 | _6、将客户端证书,导入到服务器端的Trust KeyStore中_ 15 | `keytool -import -alias clientkey -file client.crt -keystore tserver.keystore` 16 | **生成的文件分成两组,服务器端保存:kserver.keystore tserver.keystore 客户端保存:kclient.keystore tclient.kyestore** 17 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/socketserver/netty/MessageEncoder.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.socketserver.netty; 2 | 3 | import com.lance.api.business.pojo.model.ReturnModel; 4 | import com.lance.api.business.util.ComposeUtil; 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.handler.codec.MessageToByteEncoder; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * 报文组装 12 | * 13 | * @author lance 14 | */ 15 | public class MessageEncoder extends MessageToByteEncoder 16 | { 17 | @Override 18 | protected void encode(ChannelHandlerContext channelHandlerContext, ReturnModel returnModel, ByteBuf out) throws Exception 19 | { 20 | byte[] bytes = null; 21 | try 22 | { 23 | bytes = ComposeUtil.doCanProcess(returnModel.getMap(), returnModel.getServCode(), returnModel.getMsgId()); 24 | } 25 | catch (Exception e) 26 | { 27 | e.printStackTrace(); 28 | } 29 | out.writeBytes(bytes); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/wrap/config/InitServiceWrapper.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.wrap.config; 2 | 3 | import com.lance.api.business.service.wrap.business.CheckWrapper; 4 | import com.lance.api.business.service.wrap.business.InquiryWrapper; 5 | import com.lance.api.business.service.wrap.business.SaveWrapper; 6 | import com.lance.api.business.service.wrap.core.ServiceWrapperContainer; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | *

加载wrappers 12 | * 13 | * @author lance 14 | * @since 2018-10-15 15 | */ 16 | @Configuration 17 | public class InitServiceWrapper 18 | { 19 | @Bean("serviceWrapperContainer") 20 | public ServiceWrapperContainer initWrapper(InquiryWrapper inquiryWrapper, SaveWrapper saveWrapper, CheckWrapper checkWrapper) 21 | { 22 | ServiceWrapperContainer serviceWrapper = new ServiceWrapperContainer(); 23 | serviceWrapper.addService(inquiryWrapper); 24 | serviceWrapper.addService(saveWrapper); 25 | serviceWrapper.addService(checkWrapper); 26 | return serviceWrapper; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/wrap/business/CheckWrapper.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.wrap.business; 2 | 3 | import com.lance.api.business.service.wrap.core.BaseServiceWrapper; 4 | import com.lance.api.common.base.model.Communication; 5 | import com.lance.api.common.constant.ServerCode; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * 校验包装类 13 | * 14 | * @author lance 15 | */ 16 | @Slf4j 17 | @Component 18 | public class CheckWrapper extends BaseServiceWrapper 19 | { 20 | 21 | /** 22 | * 此业务包装类的servCode 23 | */ 24 | private final String servCode = ServerCode.SERVER_CODE_CHECK; 25 | 26 | /** 27 | * 获取当前servCode 28 | * 29 | * @return 30 | */ 31 | @Override 32 | public String doCode() 33 | { 34 | return servCode; 35 | } 36 | 37 | /** 38 | * 处理业务--校验 39 | * 40 | * @param params 41 | * @return 42 | * @throws Exception 43 | */ 44 | @Override 45 | public Map handle(Object... params) throws Exception 46 | { 47 | // 返回结果map 48 | return Communication.getInstance().getSuccessMap(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/socketserver/netty/MessageDecoder.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.socketserver.netty; 2 | 3 | import com.lance.api.business.pojo.model.EntryModel; 4 | import com.lance.api.business.util.ByteDataBuffer; 5 | import com.lance.api.business.util.ComposeUtil; 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandler; 8 | import io.netty.channel.ChannelHandlerContext; 9 | import io.netty.handler.codec.ByteToMessageDecoder; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * 报文解码 17 | * 18 | * @author lance 19 | */ 20 | public class MessageDecoder extends ByteToMessageDecoder 21 | { 22 | 23 | /** 24 | * 从ByteBuf中获取字节,转换成对象 25 | * 26 | * @param ctx 27 | * @param buffer 28 | * @param out 29 | * @throws Exception 30 | */ 31 | @Override 32 | protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception 33 | { 34 | int len = buffer.readableBytes(); 35 | byte[] req = new byte[len]; 36 | buffer.getBytes(0, req); 37 | 38 | ByteDataBuffer dataBuffer = new ByteDataBuffer(req); 39 | 40 | EntryModel entryModel = ComposeUtil.deSplit(dataBuffer); 41 | out.add(entryModel); 42 | buffer.skipBytes(len); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/lance/Application.java: -------------------------------------------------------------------------------- 1 | package com.lance; 2 | 3 | import com.lance.api.business.socketserver.nativesocket.ServerSocket; 4 | import com.lance.api.business.socketserver.netty.NettyServer; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.CommandLineRunner; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 10 | 11 | import java.util.concurrent.Executor; 12 | 13 | /** 14 | *

启动类 15 | * 16 | * @author lance 17 | * @since 2018-10-15 18 | */ 19 | @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 20 | public class Application implements CommandLineRunner 21 | { 22 | @Autowired 23 | private NettyServer nettyServer; 24 | @Autowired 25 | private ServerSocket serverSocket; 26 | @Autowired 27 | private Executor threadAsyncServiceProvider; 28 | 29 | public static void main(String[] args) 30 | { 31 | SpringApplication.run(Application.class, args); 32 | } 33 | 34 | @Override 35 | public void run(String... args) throws Exception 36 | { 37 | serverSocket.init(); 38 | // 启动新线程是为了原生socket与netty共存启动 39 | threadAsyncServiceProvider.execute(serverSocket); 40 | // 启动netty-socket 41 | nettyServer.start(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/config/application-dev.yaml: -------------------------------------------------------------------------------- 1 | sslSocket: 2 | port: 29999 3 | nettyPort: 9002 4 | sslFlag: true 5 | ##密钥 6 | server_key_store_password: 123456 7 | server_trust_key_store_password: 123456 8 | 9 | spring: 10 | datasource: 11 | driver-class-name: oracle.jdbc.driver.OracleDriver 12 | url: jdbc:oracle:thin:@127.0.0.1:1521:orcl 13 | username: lancedb 14 | password: lancedb 15 | # 下面为连接池的补充设置,应用到上面所有数据源中 16 | type: com.alibaba.druid.pool.DruidDataSource 17 | # 初始化大小,最小,最大 18 | initialSize: 50 19 | minIdle: 50 20 | maxActive: 50 21 | # 配置获取连接等待超时的时间 22 | maxWait: 60000 23 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 24 | timeBetweenEvictionRunsMillis: 60000 25 | # 配置一个连接在池中最小生存的时间,单位是毫秒 26 | minEvictableIdleTimeMillis: 60000 27 | validationQuery: SELECT 1 FROM DUAL 28 | testWhileIdle: true 29 | testOnBorrow: false 30 | testOnReturn: false 31 | # 打开PSCache,并且指定每个连接上PSCache的大小 32 | poolPreparedStatements: true 33 | maxPoolPreparedStatementPerConnectionSize: 100 34 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 35 | filters: stat,slf4j 36 | # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 37 | connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 38 | 39 | logging: 40 | level: 41 | druid: 42 | sql: 43 | Statement: debug 44 | ResultSet: debug 45 | org: 46 | hibernate: 47 | SQL: debug 48 | type: 49 | descriptor: 50 | sql: 51 | BasicBinder: trace 52 | BasicExtractor: trace 53 | 54 | # sftp 55 | sftp: 56 | ip: todo 57 | host: 22 58 | userName: todo 59 | userPsw: todo 60 | localFilePath: D:/sftpDir/ 61 | remoteFilePath: /home/ -------------------------------------------------------------------------------- /src/main/resources/config/application-pro.yaml: -------------------------------------------------------------------------------- 1 | sslSocket: 2 | port: 29999 3 | nettyPort: 9002 4 | sslFlag: true 5 | ##密钥 6 | server_key_store_password: longshine 7 | server_trust_key_store_password: longshine 8 | 9 | spring: 10 | datasource: 11 | driver-class-name: oracle.jdbc.driver.OracleDriver 12 | url: jdbc:oracle:thin:@127.0.0.1:1521:orcl 13 | username: lancedb 14 | password: lancedb 15 | # 下面为连接池的补充设置,应用到上面所有数据源中 16 | type: com.alibaba.druid.pool.DruidDataSource 17 | # 初始化大小,最小,最大 18 | initialSize: 50 19 | minIdle: 50 20 | maxActive: 50 21 | # 配置获取连接等待超时的时间 22 | maxWait: 60000 23 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 24 | timeBetweenEvictionRunsMillis: 60000 25 | # 配置一个连接在池中最小生存的时间,单位是毫秒 26 | minEvictableIdleTimeMillis: 60000 27 | validationQuery: SELECT 1 FROM DUAL 28 | testWhileIdle: true 29 | testOnBorrow: false 30 | testOnReturn: false 31 | # 打开PSCache,并且指定每个连接上PSCache的大小 32 | poolPreparedStatements: true 33 | maxPoolPreparedStatementPerConnectionSize: 100 34 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 35 | filters: stat,slf4j 36 | # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 37 | connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 38 | 39 | logging: 40 | level: 41 | druid: 42 | sql: 43 | Statement: debug 44 | ResultSet: debug 45 | org: 46 | hibernate: 47 | SQL: debug 48 | type: 49 | descriptor: 50 | sql: 51 | BasicBinder: trace 52 | BasicExtractor: trace 53 | 54 | # sftp 55 | sftp: 56 | ip: todo 57 | host: 22 58 | userName: todo 59 | userPsw: todo 60 | localFilePath: D:/sftpDir/ 61 | remoteFilePath: /home/ -------------------------------------------------------------------------------- /src/main/resources/config/application-test.yaml: -------------------------------------------------------------------------------- 1 | sslSocket: 2 | port: 29999 3 | nettyPort: 9002 4 | sslFlag: true 5 | ##密钥 6 | server_key_store_password: longshine 7 | server_trust_key_store_password: longshine 8 | 9 | spring: 10 | datasource: 11 | driver-class-name: oracle.jdbc.driver.OracleDriver 12 | url: jdbc:oracle:thin:@127.0.0.1:1521:orcl 13 | username: lancedb 14 | password: lancedb 15 | # 下面为连接池的补充设置,应用到上面所有数据源中 16 | type: com.alibaba.druid.pool.DruidDataSource 17 | # 初始化大小,最小,最大 18 | initialSize: 50 19 | minIdle: 50 20 | maxActive: 50 21 | # 配置获取连接等待超时的时间 22 | maxWait: 60000 23 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 24 | timeBetweenEvictionRunsMillis: 60000 25 | # 配置一个连接在池中最小生存的时间,单位是毫秒 26 | minEvictableIdleTimeMillis: 60000 27 | validationQuery: SELECT 1 FROM DUAL 28 | testWhileIdle: true 29 | testOnBorrow: false 30 | testOnReturn: false 31 | # 打开PSCache,并且指定每个连接上PSCache的大小 32 | poolPreparedStatements: true 33 | maxPoolPreparedStatementPerConnectionSize: 100 34 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 35 | filters: stat,slf4j 36 | # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 37 | connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 38 | 39 | logging: 40 | level: 41 | druid: 42 | sql: 43 | Statement: debug 44 | ResultSet: debug 45 | org: 46 | hibernate: 47 | SQL: debug 48 | type: 49 | descriptor: 50 | sql: 51 | BasicBinder: trace 52 | BasicExtractor: trace 53 | 54 | # sftp 55 | sftp: 56 | ip: todo 57 | host: 22 58 | userName: todo 59 | userPsw: todo 60 | localFilePath: D:/sftpDir/ 61 | remoteFilePath: /home/ -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/wrap/core/ServiceWrapperContainer.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.wrap.core; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | *

service包裝类容器类 8 | * 9 | * @author lance 10 | * @since 2018-10-15 11 | */ 12 | public class ServiceWrapperContainer 13 | { 14 | 15 | List services = new ArrayList<>(); 16 | 17 | /** 18 | * 添加包装类 19 | * 20 | * @param baseServiceWrapper 21 | */ 22 | public void addService(BaseServiceWrapper baseServiceWrapper) 23 | { 24 | services.add(baseServiceWrapper); 25 | } 26 | 27 | /** 28 | * 根据servCode获取service包装类 29 | * 30 | * @param servCode 31 | * @return 32 | */ 33 | public BaseServiceWrapper getService(String servCode) 34 | { 35 | for (BaseServiceWrapper baseServiceWrapper : services) 36 | { 37 | if (baseServiceWrapper.isMyDo(servCode)) 38 | { 39 | return baseServiceWrapper; 40 | } 41 | } 42 | return null; 43 | } 44 | 45 | /** 46 | * 根据servCode获取所有service包装类 47 | * 48 | * @param servCode 49 | * @return 50 | */ 51 | public List findSameService(String servCode) 52 | { 53 | 54 | List baseServiceWrapperList = new ArrayList<>(); 55 | for (BaseServiceWrapper baseServiceWrapper : services) 56 | { 57 | if (baseServiceWrapper.hasSameService() && baseServiceWrapper.isMyDo(servCode)) 58 | { 59 | baseServiceWrapperList.add(baseServiceWrapper); 60 | } 61 | } 62 | return baseServiceWrapperList; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/config/ExecutorConfig.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.scheduling.annotation.EnableAsync; 7 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 8 | 9 | import java.util.concurrent.Executor; 10 | import java.util.concurrent.ThreadPoolExecutor; 11 | 12 | /** 13 | * 创建线程池 14 | * 15 | * @author lance 16 | * @since 2018-10-15 17 | */ 18 | @Configuration 19 | @EnableAsync 20 | public class ExecutorConfig 21 | { 22 | @Value("${executor.corePoolSize}") 23 | private int corePoolSize; 24 | @Value("${executor.maxPoolSize}") 25 | private int maxPoolSize; 26 | @Value("${executor.queueCapacity}") 27 | private int queueCapacity; 28 | @Value("${executor.namePrefix}") 29 | private String namePrefix; 30 | 31 | @Bean(name = "asyncServiceExecutor") 32 | public Executor asyncServiceExecutor() 33 | { 34 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 35 | //配置核心线程数 36 | executor.setCorePoolSize(corePoolSize); 37 | //配置最大线程数 38 | executor.setMaxPoolSize(maxPoolSize); 39 | //配置队列大小 40 | executor.setQueueCapacity(queueCapacity); 41 | //配置线程池中的线程的名称前缀 42 | executor.setThreadNamePrefix(namePrefix); 43 | 44 | // rejection-policy:当pool已经达到max size的时候,如何处理新任务 45 | // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 46 | executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); 47 | //执行初始化 48 | executor.initialize(); 49 | return executor; 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/impl/ApiServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.impl; 2 | 3 | 4 | import com.lance.api.business.dao.ApiDao; 5 | import com.lance.api.business.dao.SysDao; 6 | import com.lance.api.business.pojo.dto.SampleModel; 7 | import com.lance.api.business.service.ApiService; 8 | import com.lance.api.common.base.model.JsonResult; 9 | import com.lance.api.common.constant.ResponseCode; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.math.BigDecimal; 15 | 16 | /** 17 | *

业务处理service接口实现类 18 | * 19 | * @author lance 20 | * @since 2018-10-15 21 | **/ 22 | @Slf4j 23 | @Service 24 | public class ApiServiceImpl implements ApiService 25 | { 26 | @Autowired 27 | private SysDao sysDao; 28 | @Autowired 29 | private ApiDao apiDao; 30 | 31 | /** 32 | * 获取信息 33 | * 34 | * @param key 标识符 35 | * @return 查询结果 36 | * @throws Exception 37 | */ 38 | @Override 39 | public JsonResult queryInfo(String key) throws Exception 40 | { 41 | if (key.contains("1")) 42 | { 43 | return new JsonResult(false, "查询失败", ResponseCode._1002); 44 | } 45 | return new JsonResult(true, "查询成功", new SampleModel(65535, BigDecimal.TEN)); 46 | } 47 | 48 | /** 49 | * 保存信息 50 | * 51 | * @param key 标识 52 | * @param msg 信息 53 | * @return 存储结果 54 | * @throws Exception 55 | */ 56 | @Override 57 | public JsonResult saveData(String key, String msg) throws Exception 58 | { 59 | System.out.println(key); 60 | System.out.println(msg); 61 | return new JsonResult(true, "存储成功"); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/socketserver/netty/ServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.socketserver.netty; 2 | // 记录调用方法的元信息的类 3 | 4 | import com.lance.api.business.pojo.model.EntryModel; 5 | import com.lance.api.business.pojo.model.ReturnModel; 6 | import com.lance.api.business.util.DealSocket; 7 | import io.netty.channel.ChannelHandler.Sharable; 8 | import io.netty.channel.ChannelHandlerContext; 9 | import io.netty.channel.ChannelInboundHandlerAdapter; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.slf4j.MDC; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Component; 14 | 15 | /** 16 | * netty业务处理类 17 | * 18 | * @author lance 19 | */ 20 | @Component 21 | @Sharable 22 | @Slf4j 23 | public class ServerHandler extends ChannelInboundHandlerAdapter 24 | { 25 | @Autowired 26 | private DealSocket dealSocket; 27 | 28 | @Override 29 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception 30 | { 31 | EntryModel entryModel = (EntryModel) msg; 32 | 33 | String servCode = entryModel.getHeadModel().getServCode(); 34 | String msgId = entryModel.getHeadModel().getMsgId(); 35 | 36 | // do business 37 | MDC.put("logId", msgId); 38 | ReturnModel result = dealSocket.doBusiness(servCode, msgId, entryModel); 39 | MDC.clear(); 40 | ctx.writeAndFlush(result); 41 | } 42 | 43 | @Override 44 | public void channelReadComplete(ChannelHandlerContext ctx) throws Exception 45 | { 46 | 47 | } 48 | 49 | @Override 50 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 51 | { 52 | // Close the connection when an exception is raised. 53 | cause.printStackTrace(); 54 | ctx.close(); 55 | } 56 | } -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/base/model/Communication.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.base.model; 2 | 3 | 4 | import com.lance.api.common.constant.ResponseCode; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class Communication 10 | { 11 | private static Communication communication = null; 12 | 13 | public static Communication getInstance() 14 | { 15 | if (communication == null) 16 | { 17 | communication = new Communication(); 18 | } 19 | return communication; 20 | } 21 | 22 | 23 | public Map getSuccessMap() 24 | { 25 | Map res = new HashMap<>(3); 26 | res.put("rtnCode", ResponseCode._9999.getKey()); 27 | res.put("rtnMsg", ResponseCode._9999.getValue()); 28 | res.put("extend", ""); 29 | return res; 30 | } 31 | 32 | public Map getErroMap() 33 | { 34 | Map res = new HashMap<>(3); 35 | res.put("rtnCode", ResponseCode._0009.getKey()); 36 | res.put("rtnMsg", ResponseCode._0009.getValue()); 37 | res.put("extend", ""); 38 | return res; 39 | } 40 | 41 | 42 | public Map getFailedMap(String rtnCode, String rtnMsg) 43 | { 44 | Map res = new HashMap<>(3); 45 | res.put("rtnCode", rtnCode); 46 | res.put("rtnMsg", rtnMsg); 47 | res.put("extend", ""); 48 | return res; 49 | } 50 | 51 | 52 | public Map getFailedMap(String rtnCode, String rtnMsg, String extend) 53 | { 54 | Map res = new HashMap<>(3); 55 | res.put("rtnCode", rtnCode); 56 | res.put("rtnMsg", rtnMsg); 57 | res.put("extend", extend); 58 | return res; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/com/sslsocketclient/查询.java: -------------------------------------------------------------------------------- 1 | package com.sslsocketclient; 2 | 3 | import java.io.BufferedOutputStream; 4 | import java.net.Socket; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import static com.sslsocketclient.DeSplitDemo.createSocketNote; 10 | 11 | /** 12 | * Created by me on 2018/6/7. 13 | */ 14 | public class 查询 15 | { 16 | 17 | public static void main(String[] args) throws Exception 18 | { 19 | Map map = search("2", "1"); 20 | ComposeDemo cd = new ComposeDemo(); 21 | Socket ss = null; 22 | 23 | String serverCode = (String) map.get("serverCode"); 24 | Map mapQuery = (Map) map.get("mapQuery"); 25 | ss = createSocketNote(); 26 | BufferedOutputStream bfo = new BufferedOutputStream(ss.getOutputStream()); 27 | bfo.write(cd.doCanProcess(mapQuery, serverCode)); 28 | bfo.flush(); 29 | 30 | DeSplitDemo split = new DeSplitDemo(); 31 | 32 | final byte[] buf = new byte[36000]; 33 | 34 | // 报文帧拆分的处理类 35 | ss.getInputStream().read(buf); 36 | 37 | ByteDataBuffer bdb = new ByteDataBuffer(buf); 38 | List tmpList = split.doCanProcess(bdb); 39 | // 收到的数据 40 | System.out.println("机构返回的报文:" + tmpList.toString()); 41 | ss.close(); 42 | 43 | } 44 | 45 | /** 46 | * 获取数据 47 | * 48 | * @return 49 | */ 50 | private static Map search(String key, String type) 51 | { 52 | String serverCode = "200001"; 53 | Map mapQuery = new HashMap<>(); 54 | 55 | //查询条件的类别 56 | mapQuery.put("queryType", type); 57 | //对应查询类别的查询条件 58 | mapQuery.put("queryValue", key); 59 | //预留 60 | mapQuery.put("extend", "666"); 61 | Map map = new HashMap(); 62 | map.put("serverCode", serverCode); 63 | map.put("mapQuery", mapQuery); 64 | return map; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/util/SpringContextUtil.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.util; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.NoSuchBeanDefinitionException; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.ApplicationContextAware; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * SpringContext工具类 11 | * 12 | * @author lance 13 | * @version 2018-4-18 14 | */ 15 | @Component 16 | public class SpringContextUtil implements ApplicationContextAware 17 | { 18 | 19 | /** 20 | * Spring应用上下文环境 21 | */ 22 | private static ApplicationContext applicationContext; 23 | 24 | @Override 25 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 26 | { 27 | SpringContextUtil.applicationContext = applicationContext; 28 | } 29 | 30 | public static ApplicationContext getApplicationContext() 31 | { 32 | return applicationContext; 33 | } 34 | 35 | public static Object getBean(String name) throws BeansException 36 | { 37 | return applicationContext.getBean(name); 38 | } 39 | 40 | 41 | public static Object getBean(String name, Class requiredType) throws BeansException 42 | { 43 | return applicationContext.getBean(name, requiredType); 44 | } 45 | 46 | 47 | public static boolean containsBean(String name) 48 | { 49 | return applicationContext.containsBean(name); 50 | } 51 | 52 | 53 | public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException 54 | { 55 | return applicationContext.isSingleton(name); 56 | } 57 | 58 | 59 | public static Class getType(String name) throws NoSuchBeanDefinitionException 60 | { 61 | return applicationContext.getType(name); 62 | } 63 | 64 | 65 | public static String[] getAliases(String name) throws NoSuchBeanDefinitionException 66 | { 67 | return applicationContext.getAliases(name); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/base/model/JsonResult.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.base.model; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.JsonInclude; 5 | 6 | import java.util.HashMap; 7 | 8 | /** 9 | * 返回json结果封装类 10 | * 11 | * @author lance 12 | * @since 2017-11-24 13 | */ 14 | @JsonInclude(value = JsonInclude.Include.NON_NULL) 15 | public class JsonResult extends HashMap 16 | { 17 | /** 18 | * 是否成功 19 | */ 20 | private final String success = "success"; 21 | 22 | /** 23 | * 返回信息 24 | */ 25 | private final String message = "message"; 26 | 27 | /** 28 | * 返回数据 29 | */ 30 | private final String data = "data"; 31 | 32 | public JsonResult() 33 | { 34 | super(); 35 | this.setSuccess(true); 36 | } 37 | 38 | public JsonResult(Object data) 39 | { 40 | super(); 41 | this.setSuccess(true); 42 | this.setData(data); 43 | } 44 | 45 | public JsonResult(boolean success, String message) 46 | { 47 | super(); 48 | this.setSuccess(success); 49 | this.setMessage(message); 50 | } 51 | 52 | public JsonResult(boolean success, String message, Object data) 53 | { 54 | super(); 55 | this.setSuccess(success); 56 | this.setMessage(message); 57 | this.setData(data); 58 | } 59 | 60 | public boolean getSuccess() 61 | { 62 | return (Boolean) this.get(success); 63 | } 64 | 65 | public JsonResult setSuccess(boolean value) 66 | { 67 | this.put(success, value); 68 | return this; 69 | } 70 | 71 | public String getMessage() 72 | { 73 | return (String) this.get(message); 74 | } 75 | 76 | public JsonResult setMessage(String value) 77 | { 78 | this.put(message, value); 79 | return this; 80 | } 81 | 82 | public Object getData() 83 | { 84 | return this.get(data); 85 | } 86 | 87 | public JsonResult setData(Object value) 88 | { 89 | this.put(data, value); 90 | return this; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/sslsocketclient/HexStringUtils.java: -------------------------------------------------------------------------------- 1 | package com.sslsocketclient; 2 | 3 | public class HexStringUtils 4 | { 5 | 6 | private static final char[] DIGITS_HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 7 | 8 | protected static char[] encodeHex(byte[] data) 9 | { 10 | int l = data.length; 11 | char[] out = new char[l << 1]; 12 | for (int i = 0, j = 0; i < l; i++) 13 | { 14 | out[j++] = DIGITS_HEX[(0xF0 & data[i]) >>> 4]; 15 | out[j++] = DIGITS_HEX[0x0F & data[i]]; 16 | } 17 | return out; 18 | } 19 | 20 | protected static byte[] decodeHex(char[] data) 21 | { 22 | int len = data.length; 23 | if ((len & 0x01) != 0) 24 | { 25 | throw new RuntimeException("字符个数应该为偶数"); 26 | } 27 | byte[] out = new byte[len >> 1]; 28 | for (int i = 0, j = 0; j < len; i++) 29 | { 30 | int f = toDigit(data[j], j) << 4; 31 | j++; 32 | f |= toDigit(data[j], j); 33 | j++; 34 | out[i] = (byte) (f & 0xFF); 35 | } 36 | return out; 37 | } 38 | 39 | protected static int toDigit(char ch, int index) 40 | { 41 | int digit = Character.digit(ch, 16); 42 | if (digit == -1) 43 | { 44 | throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index); 45 | } 46 | return digit; 47 | } 48 | 49 | public static String toHex(String str) 50 | { 51 | return new String(encodeHex(str.getBytes())); 52 | } 53 | 54 | public static String toBinary(String str) 55 | { 56 | char[] strChar = str.toCharArray(); 57 | String result = ""; 58 | for (int i = 0; i < strChar.length; i++) 59 | { 60 | result += Integer.toBinaryString(strChar[i]) + " "; 61 | } 62 | return result; 63 | } 64 | 65 | public static String fromHex(String hex) 66 | { 67 | return new String(decodeHex(hex.toCharArray())); 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/wrap/business/SaveWrapper.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.wrap.business; 2 | 3 | 4 | import com.lance.api.business.pojo.model.EntryBodyModel; 5 | import com.lance.api.business.pojo.model.EntryModel; 6 | import com.lance.api.business.service.ApiService; 7 | import com.lance.api.business.service.wrap.core.BaseServiceWrapper; 8 | import com.lance.api.common.base.model.Communication; 9 | import com.lance.api.common.base.model.JsonResult; 10 | import com.lance.api.common.constant.ResponseCode; 11 | import com.lance.api.common.constant.ServerCode; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Component; 15 | 16 | import java.util.Map; 17 | 18 | /** 19 | * 存储包装类 20 | * 21 | * @author lance 22 | */ 23 | @Slf4j 24 | @Component 25 | public class SaveWrapper extends BaseServiceWrapper 26 | { 27 | /** 28 | * 此业务包装类的servCode 29 | */ 30 | private final String servCode = ServerCode.SERVER_CODE_SAVE; 31 | @Autowired 32 | private ApiService apiService; 33 | 34 | @Override 35 | public String doCode() 36 | { 37 | return servCode; 38 | } 39 | 40 | @Override 41 | public Map handle(Object... params) throws Exception 42 | { 43 | Map resultMap; 44 | ResponseCode failedMsg = null; 45 | 46 | EntryModel entryModel = (EntryModel) params[0]; 47 | EntryBodyModel bodyModel = entryModel.getBodyModel(); 48 | 49 | String key = bodyModel.getQueryValue(); 50 | String type = bodyModel.getQueryValue(); 51 | 52 | JsonResult saveResult = null; 53 | try 54 | { 55 | saveResult = apiService.saveData(key, type); 56 | } 57 | catch (Exception e) 58 | { 59 | log.error("系统发生异常: {}", e.getMessage()); 60 | e.printStackTrace(); 61 | 62 | return Communication.getInstance().getErroMap(); 63 | } 64 | 65 | if (saveResult.getSuccess()) 66 | { 67 | resultMap = Communication.getInstance().getSuccessMap(); 68 | } 69 | else 70 | { 71 | failedMsg = (ResponseCode) saveResult.getData(); 72 | resultMap = Communication.getInstance().getFailedMap(failedMsg.getKey(), failedMsg.getValue()); 73 | } 74 | return resultMap; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/service/wrap/business/InquiryWrapper.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.service.wrap.business; 2 | 3 | import com.lance.api.business.pojo.dto.SampleModel; 4 | import com.lance.api.business.pojo.model.EntryBodyModel; 5 | import com.lance.api.business.pojo.model.EntryModel; 6 | import com.lance.api.business.pojo.model.FieldNameModel; 7 | import com.lance.api.business.service.ApiService; 8 | import com.lance.api.business.service.wrap.core.BaseServiceWrapper; 9 | import com.lance.api.common.base.model.Communication; 10 | import com.lance.api.common.base.model.JsonResult; 11 | import com.lance.api.common.constant.ResponseCode; 12 | import com.lance.api.common.constant.ServerCode; 13 | import lombok.extern.slf4j.Slf4j; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Component; 16 | 17 | import java.util.Map; 18 | 19 | /** 20 | * 查询包装类 21 | * 22 | * @author lance 23 | * @since 2018-10-15 24 | */ 25 | @Slf4j 26 | @Component 27 | public class InquiryWrapper extends BaseServiceWrapper 28 | { 29 | /** 30 | * 此业务包装类的servCode 31 | */ 32 | private final String servCode = ServerCode.SERVER_CODE_QUERY; 33 | @Autowired 34 | private ApiService apiService; 35 | 36 | @Override 37 | public String doCode() 38 | { 39 | return servCode; 40 | } 41 | 42 | @Override 43 | @SuppressWarnings("unchecked") 44 | public Map handle(Object... params) throws Exception 45 | { 46 | // 返回结果map 47 | Map resultMap; 48 | ResponseCode failedMsg = null; 49 | 50 | // 获取传入参数 51 | EntryModel entryModel = (EntryModel) params[0]; 52 | EntryBodyModel bodyModel = entryModel.getBodyModel(); 53 | // 获取查询标识 54 | String queryValue = bodyModel.getQueryValue(); 55 | 56 | // 查询查询信息 57 | JsonResult queryInfo = apiService.queryInfo(queryValue); 58 | 59 | // 如果获取成功 60 | if (queryInfo.getSuccess()) 61 | { 62 | SampleModel model = (SampleModel) queryInfo.getData(); 63 | resultMap = Communication.getInstance().getSuccessMap(); 64 | resultMap.put(FieldNameModel.RECORD_COUNT, model.getCount()); 65 | resultMap.put(FieldNameModel.RECORD_AMT, model.getAmt()); 66 | } 67 | else 68 | { 69 | failedMsg = (ResponseCode) queryInfo.getData(); 70 | resultMap = Communication.getInstance().getFailedMap(failedMsg.getKey(), failedMsg.getValue()); 71 | } 72 | return resultMap; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/constant/ResponseCode.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.constant; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 返回编码 8 | * 9 | * @author lance 10 | * @since 2018-10-17 11 | */ 12 | 13 | public enum ResponseCode 14 | { 15 | //成功代码 16 | _9999("9999", "交易成功"), 17 | //程序类错误 18 | /** 19 | * 报文的格式和标准的报文格式不一致。 20 | */ 21 | _0000("0000", "报文格式错误"), 22 | /** 23 | * 销账机构处理的时候出现异常,不会退钱 24 | */ 25 | _0009("0009", "系统异常"), 26 | /** 27 | * 查询不合法 28 | */ 29 | _1002("1002", "查询不合法"); 30 | 31 | 32 | private String key; 33 | private String value; 34 | private Map valuesMap = new HashMap<>(); 35 | private String code; 36 | 37 | public String getValue(String s) 38 | { 39 | return valuesMap.get(s); 40 | } 41 | 42 | public static class Values 43 | { 44 | 45 | 46 | public Values(String key, String value) 47 | { 48 | this.key = key; 49 | this.value = value; 50 | } 51 | 52 | private String key; 53 | private String value; 54 | 55 | public String getKey() 56 | { 57 | return key; 58 | } 59 | 60 | public void setKey(String key) 61 | { 62 | this.key = key; 63 | } 64 | 65 | public String getValue() 66 | { 67 | return value; 68 | } 69 | 70 | public void setValue(String value) 71 | { 72 | this.value = value; 73 | } 74 | 75 | } 76 | 77 | private ResponseCode(String code, Values... values) 78 | { 79 | this.code = code; 80 | if (values != null && values.length > 0) 81 | { 82 | this.code = code; 83 | this.key = values[0].getKey(); 84 | this.value = values[0].getValue(); 85 | 86 | for (Values v : values) 87 | { 88 | valuesMap.put(v.getKey(), v.getValue()); 89 | } 90 | } 91 | } 92 | 93 | private ResponseCode(String key, String value) 94 | { 95 | this.code = key; 96 | this.key = key; 97 | this.value = value; 98 | } 99 | 100 | 101 | public String getCode() 102 | { 103 | return code; 104 | } 105 | 106 | public String getKey() 107 | { 108 | return this.key; 109 | } 110 | 111 | public String getValue() 112 | { 113 | return this.value; 114 | } 115 | 116 | @Override 117 | public String toString() 118 | { 119 | return this.key + ":" + this.value; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/test/java/com/sslsocketclient/ComposeDemo.java: -------------------------------------------------------------------------------- 1 | package com.sslsocketclient; 2 | 3 | 4 | import com.alibaba.fastjson.JSONObject; 5 | 6 | import java.io.UnsupportedEncodingException; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Date; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | 13 | /** 14 | * 报文组装 15 | */ 16 | public class ComposeDemo 17 | { 18 | 19 | protected byte[] doCanProcess(Map paraMap, String serverCode) throws Exception 20 | { 21 | JSONObject jsonObject = new JSONObject(); 22 | Map map = new HashMap(); 23 | Map headMap = new HashMap(); 24 | // 服务编码 25 | String servCode = serverCode; 26 | headMap.put("version", "1.0.0"); 27 | // 服务编码 28 | headMap.put("servCode", servCode); 29 | // msgId 32位不可重复的流水 30 | 31 | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); 32 | 33 | Date msgtime = new Date(); 34 | headMap.put("msgId", "test" + sdf.format(msgtime)); 35 | 36 | headMap.put("msgTime", sdf.format(msgtime)); 37 | headMap.put("extend", ""); 38 | map.put("head", headMap); 39 | map.put("body", paraMap); 40 | 41 | String message = jsonObject.toJSONString(map).replace("\\", ""); 42 | 43 | System.out.println("请求的报文为:" + message); 44 | ByteDataBuffer bdb = new ByteDataBuffer(); 45 | bdb.setInBigEndian(false); 46 | // 开始字节 47 | bdb.writeInt8((byte) 0x68); 48 | int len = Integer.parseInt(getLen(message, 4)); 49 | // 用于计算数据域的长度是否大于4字节 50 | // 报文长度 51 | bdb.writeInt32(len); 52 | // 服务编码 53 | bdb.writeString(servCode, 6); 54 | // 报文frame 55 | bdb.writeBytes(message.getBytes()); 56 | // 结束字节 57 | bdb.writeInt8((byte) 0x16); 58 | return bdb.getBytes(); 59 | } 60 | 61 | 62 | /** 63 | * 计算报文长度,不足四位左补零 64 | * 65 | * @param text 报文信息 66 | * @param needlen 报文长度规定的字符数 67 | * @return 68 | */ 69 | public static String getLen(String text, int needlen) 70 | { 71 | if (text != null) 72 | { 73 | int len; 74 | try 75 | { 76 | len = text.getBytes("utf-8").length; 77 | String lenStr = String.valueOf(len); 78 | StringBuffer sb = new StringBuffer(lenStr); 79 | while (sb.length() < needlen) 80 | { 81 | sb.insert(0, "0"); 82 | 83 | } 84 | return sb.toString(); 85 | } 86 | catch (UnsupportedEncodingException e) 87 | { 88 | e.printStackTrace(); 89 | } 90 | } 91 | return null; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${log.path}/info.log 9 | 10 | %d{yyyy-MM-dd HH:mm:ss.SSS}-[%-5p]|%X{logId}| %-40.40logger{39}: %m%n 11 | utf-8 12 | 13 | 14 | ${log.path}/backup-info.%d{yyyy-MM-dd}.%i.zip 15 | 60MB 16 | 31 17 | 10GB 18 | 19 | 20 | 21 | 22 | ${log.path}/warn.log 23 | 24 | %d{yyyy-MM-dd HH:mm:ss.SSS}-[%-5p]|%X{logId}| %-40.40logger{39}: %m%n 25 | utf-8 26 | 27 | 28 | ${log.path}/backup-warn.%d{yyyy-MM-dd}.%i.zip 29 | 60MB 30 | 31 31 | 10GB 32 | 33 | 34 | WARN 35 | ACCEPT 36 | DENY 37 | 38 | 39 | 40 | 41 | ${log.path}/error.log 42 | 43 | %d{yyyy-MM-dd HH:mm:ss.SSS}-[%-5p]|%X{logId}| %-40.40logger{39}: %m%n 44 | utf-8 45 | 46 | 47 | ${log.path}/backup-error.%d{yyyy-MM-dd}.%i.zip 48 | 60MB 49 | 31 50 | 10GB 51 | 52 | 53 | ERROR 54 | ACCEPT 55 | DENY 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/socketserver/nativesocket/ServerSocket.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.socketserver.nativesocket; 2 | 3 | 4 | import com.lance.api.business.util.DealSocket; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.core.io.ClassPathResource; 9 | import org.springframework.core.io.Resource; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.net.ssl.KeyManagerFactory; 13 | import javax.net.ssl.SSLContext; 14 | import javax.net.ssl.SSLServerSocket; 15 | import javax.net.ssl.TrustManagerFactory; 16 | import java.net.Socket; 17 | import java.security.KeyStore; 18 | 19 | 20 | /** 21 | * ssl socket 22 | * 23 | * @author lance 24 | * @since 2018-10-10 25 | */ 26 | @Component("serverSocket") 27 | @Slf4j 28 | public class ServerSocket implements Runnable 29 | { 30 | @Value("${sslSocket.port}") 31 | private int port; 32 | @Value("${sslSocket.server_key_store_password}") 33 | private String serverKeyStorePassword; 34 | @Value("${sslSocket.server_trust_key_store_password}") 35 | private String serverTrustKeyStorePassword; 36 | 37 | @Autowired 38 | private DealSocket dealSocket; 39 | 40 | private SSLServerSocket serverSocket; 41 | 42 | 43 | /** 44 | * 启动程序 45 | */ 46 | @Override 47 | public void run() 48 | { 49 | if (serverSocket == null) 50 | { 51 | log.error("ERROR:启动socket服务失败"); 52 | return; 53 | } 54 | while (true) 55 | { 56 | try 57 | { 58 | Socket socket = serverSocket.accept(); 59 | 60 | dealSocket.analysisAndDealMsg(socket); 61 | } 62 | catch (Exception e) 63 | { 64 | e.printStackTrace(); 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * 初始化 71 | */ 72 | public void init() 73 | { 74 | try 75 | { 76 | SSLContext ctx = SSLContext.getInstance("SSL"); 77 | 78 | KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 79 | TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 80 | 81 | KeyStore ks = KeyStore.getInstance("JKS"); 82 | KeyStore tks = KeyStore.getInstance("JKS"); 83 | Resource fileResourceK = new ClassPathResource("keystores/kserver.keystore"); 84 | Resource fileResourceT = new ClassPathResource("keystores/tserver.keystore"); 85 | ks.load(fileResourceK.getInputStream(), serverKeyStorePassword.toCharArray()); 86 | tks.load(fileResourceT.getInputStream(), serverTrustKeyStorePassword.toCharArray()); 87 | 88 | kmf.init(ks, serverKeyStorePassword.toCharArray()); 89 | tmf.init(tks); 90 | 91 | ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 92 | 93 | serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(port); 94 | serverSocket.setNeedClientAuth(true); 95 | } 96 | catch (Exception e) 97 | { 98 | e.printStackTrace(); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/test/java/com/sslsocketclient/DeSplitDemo.java: -------------------------------------------------------------------------------- 1 | package com.sslsocketclient; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | 5 | import javax.net.ssl.KeyManagerFactory; 6 | import javax.net.ssl.SSLContext; 7 | import javax.net.ssl.TrustManagerFactory; 8 | import java.io.FileInputStream; 9 | import java.net.Socket; 10 | import java.security.KeyStore; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | public class DeSplitDemo 16 | { 17 | private static final byte BLOCK_START_SIGN = 0x68; 18 | private static final String ENCODING = "UTF-8"; 19 | //服务端地址 20 | private static final String serverHost = "127.0.0.1"; 21 | //服务端监听端口 22 | private static final int serverPort = 9002; 23 | //客户端私钥密码 24 | private static final String clientKeyPassword = "123456"; 25 | private static final String kcp = "src\\test\\java\\com\\sslsocketclient\\res\\kclient.keystore"; 26 | //客户端信任证书密码 27 | private static final String trustKeyPassword = "123456"; 28 | private static final String tcp = "src\\test\\java\\com\\sslsocketclient\\res\\tclient.keystore"; 29 | 30 | public static Socket createSocketNote() 31 | { 32 | try 33 | { 34 | FileInputStream clientPrivateKey = new FileInputStream(kcp); 35 | FileInputStream trustKey = new FileInputStream(tcp);//客户端信任证书列表,即服务端证书 36 | 37 | SSLContext ctx = SSLContext.getInstance("SSL"); 38 | KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 39 | TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 40 | KeyStore ks = KeyStore.getInstance("JKS"); 41 | KeyStore tks = KeyStore.getInstance("JKS"); 42 | 43 | ks.load(clientPrivateKey, clientKeyPassword.toCharArray()); 44 | tks.load(trustKey, trustKeyPassword.toCharArray()); 45 | 46 | kmf.init(ks, clientKeyPassword.toCharArray()); 47 | tmf.init(tks); 48 | 49 | ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 50 | 51 | return (Socket) ctx.getSocketFactory().createSocket(serverHost, serverPort); 52 | } 53 | catch (Exception e) 54 | { 55 | e.printStackTrace(); 56 | } 57 | return null; 58 | } 59 | 60 | protected List doCanProcess(ByteDataBuffer obj) throws Exception 61 | { 62 | List list = new ArrayList(); 63 | Map bodyMap; 64 | Map headMap; 65 | ByteDataBuffer databuf = obj; 66 | String sourceReceivedStr = new String(databuf.getBytes()); 67 | System.out.println("原始报文为:" + sourceReceivedStr); 68 | System.out.println("字节数:" + sourceReceivedStr.length()); 69 | System.out.println("报文转为16进制: \n" + HexStringUtils.toHex(sourceReceivedStr)); 70 | databuf.setEncoding(ENCODING); 71 | databuf.setInBigEndian(false); 72 | int totalLen = 0; // 长度 73 | byte sign = databuf.readInt8(); 74 | if (sign != BLOCK_START_SIGN) 75 | { 76 | System.out.println("无法找到起始标记!"); 77 | } 78 | 79 | totalLen = databuf.readInt32(); 80 | databuf.readString(6); 81 | byte[] dataBytes = new byte[totalLen]; 82 | databuf.readBytes(dataBytes); 83 | String message = new String(dataBytes); 84 | System.out.println("原始返回报文为:\n" + message + "\n"); 85 | // 报文是json格式,把json报文转换成Map类型的 86 | Map messageMap = JSON.parseObject(message, Map.class); 87 | bodyMap = (Map) messageMap.get("body"); 88 | headMap = (Map) messageMap.get("head"); 89 | list.add(headMap); 90 | list.add(bodyMap); 91 | return list; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/config/DruidConfig.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.config; 2 | 3 | 4 | import com.alibaba.druid.filter.logging.Slf4jLogFilter; 5 | import com.alibaba.druid.pool.DruidDataSource; 6 | import lombok.AccessLevel; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import org.springframework.boot.context.properties.ConfigurationProperties; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 13 | import org.springframework.transaction.PlatformTransactionManager; 14 | import org.springframework.transaction.annotation.EnableTransactionManagement; 15 | 16 | import javax.sql.DataSource; 17 | import java.sql.SQLException; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | @Getter 22 | @Setter(AccessLevel.PUBLIC) 23 | @ConfigurationProperties(prefix = "spring.datasource") 24 | @Configuration 25 | @EnableTransactionManagement 26 | public class DruidConfig 27 | { 28 | private String url; 29 | private String username; 30 | private String password; 31 | private String driverClassName; 32 | private int initialSize; 33 | private int minIdle; 34 | private int maxActive; 35 | private int maxWait; 36 | private int timeBetweenEvictionRunsMillis; 37 | private int minEvictableIdleTimeMillis; 38 | private String validationQuery; 39 | private boolean testWhileIdle; 40 | private boolean testOnBorrow; 41 | private boolean testOnReturn; 42 | private boolean poolPreparedStatements; 43 | private int maxPoolPreparedStatementPerConnectionSize; 44 | private String filters; 45 | private String connectionProperties; 46 | 47 | @Bean 48 | public DataSource dataSource() 49 | { 50 | DruidDataSource datasource = new DruidDataSource(); 51 | datasource.setUrl(url); 52 | datasource.setUsername(username); 53 | datasource.setPassword(password); 54 | datasource.setDriverClassName(driverClassName); 55 | datasource.setInitialSize(initialSize); 56 | datasource.setMinIdle(minIdle); 57 | datasource.setMaxActive(maxActive); 58 | datasource.setMaxWait(maxWait); 59 | datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); 60 | datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); 61 | datasource.setValidationQuery(validationQuery); 62 | datasource.setTestWhileIdle(testWhileIdle); 63 | datasource.setTestOnBorrow(testOnBorrow); 64 | datasource.setTestOnReturn(testOnReturn); 65 | datasource.setPoolPreparedStatements(poolPreparedStatements); 66 | datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); 67 | List list = new ArrayList(); 68 | list.add(logFilter()); 69 | datasource.setProxyFilters(list); 70 | try 71 | { 72 | datasource.setFilters(filters); 73 | } 74 | catch (SQLException e) 75 | { 76 | System.err.println("druid configuration initialization filter: " + e); 77 | } 78 | datasource.setConnectionProperties(connectionProperties); 79 | return datasource; 80 | } 81 | 82 | @Bean 83 | public PlatformTransactionManager transactionManager() throws SQLException 84 | { 85 | return new DataSourceTransactionManager(dataSource()); 86 | } 87 | 88 | @Bean 89 | public Slf4jLogFilter logFilter() 90 | { 91 | Slf4jLogFilter slf4jLogFilter = new Slf4jLogFilter(); 92 | slf4jLogFilter.setConnectionLogEnabled(false); 93 | // 输出sql连接状态 94 | slf4jLogFilter.setStatementLogEnabled(false); 95 | // 输出sql运行结果 96 | slf4jLogFilter.setResultSetLogEnabled(true); 97 | // sql预编译占位符赋值 98 | slf4jLogFilter.setStatementExecutableSqlLogEnable(true); 99 | return slf4jLogFilter; 100 | } 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.lance 7 | springbootNettySslSocketDemo 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | springbootNettySslSocketDemo 12 | an socket demo 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.4.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 1.1.10 27 | 1.2.33 28 | 11.0.1.0 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-aop 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-devtools 39 | runtime 40 | true 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-configuration-processor 45 | true 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-starter-test 50 | test 51 | 52 | 53 | 54 | org.projectlombok 55 | lombok 56 | true 57 | 58 | 59 | 60 | com.alibaba 61 | druid 62 | ${alibaba.druid.version} 63 | 64 | 65 | 66 | oracle 67 | ojdbc6 68 | ${oracle.driver.version} 69 | 70 | 71 | 72 | commons-beanutils 73 | commons-beanutils 74 | 1.9.3 75 | 76 | 77 | 78 | commons-lang 79 | commons-lang 80 | 2.6 81 | 82 | 83 | 84 | io.netty 85 | netty-all 86 | 4.1.33.Final 87 | 88 | 89 | com.alibaba 90 | fastjson 91 | 1.1.26 92 | 93 | 94 | com.fasterxml.jackson.core 95 | jackson-databind 96 | 2.9.1 97 | 98 | 99 | com.jcraft 100 | jsch 101 | 0.1.54 102 | 103 | 104 | org.springframework 105 | spring-jdbc 106 | 5.0.0.RC4 107 | 108 | 109 | 110 | 111 | springbootNettySslSocketDemo 112 | 113 | 114 | org.springframework.boot 115 | spring-boot-maven-plugin 116 | 117 | 118 | true 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/util/ComposeUtil.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.util; 2 | 3 | 4 | import com.alibaba.fastjson.JSON; 5 | import com.alibaba.fastjson.JSONObject; 6 | import com.alibaba.fastjson.TypeReference; 7 | import com.lance.api.business.pojo.model.EntryBodyModel; 8 | import com.lance.api.business.pojo.model.EntryHeadModel; 9 | import com.lance.api.business.pojo.model.EntryModel; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.annotation.Value; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.io.UnsupportedEncodingException; 15 | import java.text.SimpleDateFormat; 16 | import java.util.Date; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | 21 | /** 22 | *

报文组装解析类 23 | * 24 | * @author lance 25 | * @since 2018-10-11 26 | */ 27 | @Slf4j 28 | @Component 29 | public class ComposeUtil 30 | { 31 | private static final byte BLOCK_BGN_SIGN = 0x68; 32 | private static final byte BLOCK_END_SIGN = 0x16; 33 | private static final String ENCODING = "UTF-8"; 34 | 35 | /** 36 | * 组装报文 37 | * 38 | * @param paraMap 39 | * @param serverCode 40 | * @param msgId 41 | * @return 42 | * @throws Exception 43 | */ 44 | public static byte[] doCanProcess(Map paraMap, String serverCode, String msgId) throws Exception 45 | { 46 | Map map = new HashMap<>(); 47 | Map headMap = new HashMap<>(); 48 | // 服务编码 49 | String servCode = serverCode; 50 | headMap.put("version", "1.0.0"); 51 | // 服务编码 52 | headMap.put("servCode", servCode); 53 | 54 | // msgId 32位不可重复的流水 55 | headMap.put("msgId", msgId); 56 | headMap.put("msgTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); 57 | headMap.put("extend", ""); 58 | map.put("head", headMap); 59 | map.put("body", paraMap); 60 | String message = JSONObject.toJSONString(map).replace("\\", ""); 61 | 62 | log.info("返回的报文为:\n{}", message); 63 | ByteDataBuffer bdb = new ByteDataBuffer(); 64 | bdb.setInBigEndian(false); 65 | // 开始字节 66 | bdb.writeInt8((byte) BLOCK_BGN_SIGN); 67 | int len = Integer.parseInt(getLen(message, 4)); 68 | // 用于计算数据域的长度是否大于4字节 69 | // 报文长度 70 | bdb.writeInt32(len); 71 | // 服务编码 72 | bdb.writeString(servCode, 6); 73 | // 报文frame 74 | bdb.writeBytes(message.getBytes()); 75 | // 结束字节 76 | bdb.writeInt8((byte) BLOCK_END_SIGN); 77 | return bdb.getBytes(); 78 | } 79 | 80 | /** 81 | * 解析报文 82 | * 83 | * @param obj 84 | * @return 85 | * @throws Exception 86 | */ 87 | public static EntryModel deSplit(ByteDataBuffer obj) throws Exception 88 | { 89 | ByteDataBuffer dataBuf = obj; 90 | dataBuf.setEncoding(ENCODING); 91 | dataBuf.setInBigEndian(false); 92 | // 长度 93 | int totalLen = 0; 94 | byte sign = dataBuf.readInt8(); 95 | if (sign != BLOCK_BGN_SIGN) 96 | { 97 | log.info("无法找到起始标记!"); 98 | return null; 99 | } 100 | totalLen = dataBuf.readInt32(); 101 | dataBuf.readString(6); 102 | byte[] dataBytes = new byte[totalLen]; 103 | dataBuf.readBytes(dataBytes); 104 | String message = new String(dataBytes); 105 | log.info("请求的报文为:\n{}", message); 106 | 107 | // 报文是json格式,把json报文转换成对象类型的 108 | EntryModel entryModel = JSON.parseObject(message, EntryModel.class); 109 | EntryHeadModel headModel = JSON.parseObject(entryModel.getHead(), new TypeReference() 110 | { 111 | }); 112 | EntryBodyModel bodyModel = JSON.parseObject(entryModel.getBody(), new TypeReference() 113 | { 114 | }); 115 | entryModel.setHeadModel(headModel); 116 | entryModel.setBodyModel(bodyModel); 117 | 118 | return entryModel; 119 | } 120 | 121 | 122 | /** 123 | * 计算报文长度,不足四位左补零 124 | * 125 | * @param text 报文信息 126 | * @param needLen 报文长度规定的字符数 127 | * @return 128 | */ 129 | private static String getLen(String text, int needLen) 130 | { 131 | if (text != null) 132 | { 133 | int len; 134 | try 135 | { 136 | len = text.getBytes("utf-8").length; 137 | String lenStr = String.valueOf(len); 138 | StringBuffer sb = new StringBuffer(lenStr); 139 | while (sb.length() < needLen) 140 | { 141 | sb.insert(0, "0"); 142 | 143 | } 144 | return sb.toString(); 145 | } 146 | catch (UnsupportedEncodingException e) 147 | { 148 | e.printStackTrace(); 149 | } 150 | } 151 | return null; 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/socketserver/netty/NettyServer.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.socketserver.netty; 2 | 3 | 4 | import io.netty.bootstrap.ServerBootstrap; 5 | import io.netty.channel.*; 6 | import io.netty.channel.nio.NioEventLoopGroup; 7 | import io.netty.channel.socket.SocketChannel; 8 | import io.netty.channel.socket.nio.NioServerSocketChannel; 9 | import io.netty.handler.ssl.SslHandler; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.core.io.ClassPathResource; 14 | import org.springframework.stereotype.Component; 15 | 16 | import javax.annotation.PreDestroy; 17 | import javax.net.ssl.KeyManagerFactory; 18 | import javax.net.ssl.SSLContext; 19 | import javax.net.ssl.SSLEngine; 20 | import javax.net.ssl.TrustManagerFactory; 21 | import java.security.KeyStore; 22 | 23 | /** 24 | * netty服务启动类 25 | * 26 | * @author lance 27 | */ 28 | @Component 29 | @Slf4j 30 | public class NettyServer extends ChannelInitializer 31 | { 32 | @Value("${sslSocket.nettyPort}") 33 | private int port; 34 | @Value("${sslSocket.sslFlag:false}") 35 | private boolean ssl; 36 | @Value("${sslSocket.server_key_store_password}") 37 | private String serverKeyStorePassword; 38 | @Value("${sslSocket.server_trust_key_store_password}") 39 | private String serverTrustKeyStorePassWord; 40 | 41 | private static final EventLoopGroup BOSS_GROUP = new NioEventLoopGroup(); 42 | private static final EventLoopGroup WORKER_GROUP = new NioEventLoopGroup(); 43 | 44 | /** 45 | * 业务处理器 46 | */ 47 | @Autowired 48 | private ServerHandler serverHandler; 49 | 50 | /** 51 | * 关闭服务 52 | */ 53 | @PreDestroy 54 | public void close() 55 | { 56 | log.info("关闭服务...."); 57 | BOSS_GROUP.shutdownGracefully(); 58 | WORKER_GROUP.shutdownGracefully(); 59 | } 60 | 61 | /** 62 | * 开启服务 63 | */ 64 | public void start() throws Exception 65 | { 66 | final SSLContext sslCtx; 67 | if (ssl) 68 | { 69 | sslCtx = SSLContext.getInstance("SSL"); 70 | 71 | KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 72 | TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 73 | 74 | KeyStore ks = KeyStore.getInstance("JKS"); 75 | KeyStore tks = KeyStore.getInstance("JKS"); 76 | 77 | org.springframework.core.io.Resource frk = new ClassPathResource("keystores/kserver.keystore"); 78 | org.springframework.core.io.Resource frt = new ClassPathResource("keystores/tserver.keystore"); 79 | ks.load(frk.getInputStream(), serverKeyStorePassword.toCharArray()); 80 | tks.load(frt.getInputStream(), serverTrustKeyStorePassWord.toCharArray()); 81 | 82 | kmf.init(ks, serverKeyStorePassword.toCharArray()); 83 | tmf.init(tks); 84 | 85 | sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 86 | } 87 | else 88 | { 89 | sslCtx = null; 90 | } 91 | ServerBootstrap serverBootstrap = new ServerBootstrap(); 92 | serverBootstrap.group(BOSS_GROUP, WORKER_GROUP); 93 | serverBootstrap.channel(NioServerSocketChannel.class); 94 | serverBootstrap.option(ChannelOption.SO_BACKLOG, 100); 95 | 96 | try 97 | { 98 | //设置事件处理 99 | serverBootstrap.childHandler(new ChannelInitializer() 100 | { 101 | @Override 102 | protected void initChannel(SocketChannel ch) throws Exception 103 | { 104 | if (sslCtx != null) 105 | { 106 | SSLEngine sslEngine = sslCtx.createSSLEngine(); 107 | sslEngine.setUseClientMode(false); 108 | ch.pipeline().addFirst(new SslHandler(sslEngine)); 109 | } 110 | ChannelPipeline pipeline = ch.pipeline(); 111 | // 解码器 112 | pipeline.addLast(new MessageDecoder()); 113 | // 编码器 114 | pipeline.addLast(new MessageEncoder()); 115 | // 业务处理器 116 | pipeline.addLast(serverHandler); 117 | 118 | } 119 | }); 120 | log.info("netty服务在[{}]端口启动监听", port); 121 | ChannelFuture future = serverBootstrap.bind(port).sync(); 122 | future.channel().closeFuture().sync(); 123 | } 124 | catch (InterruptedException e) 125 | { 126 | log.info("[出现异常] 释放资源"); 127 | BOSS_GROUP.shutdownGracefully(); 128 | WORKER_GROUP.shutdownGracefully(); 129 | } 130 | } 131 | 132 | @Override 133 | protected void initChannel(Channel channel) throws Exception 134 | { 135 | 136 | } 137 | } -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/core/annotation/impl/ValidationUtils.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.core.annotation.impl; 2 | 3 | 4 | import com.lance.api.common.core.annotation.Validation; 5 | import org.springframework.util.Assert; 6 | import org.springframework.util.StringUtils; 7 | 8 | import java.lang.annotation.Annotation; 9 | import java.lang.reflect.Field; 10 | import java.util.Arrays; 11 | 12 | /** 13 | * @author lance 14 | * 用于参数校验 15 | */ 16 | @SuppressWarnings({"rawtypes", "unused", "unchecked"}) 17 | public final class ValidationUtils 18 | { 19 | /** 20 | * 参数校验. 21 | * 22 | * @param obj pojo对象 23 | * @return 校验结果 24 | * @throws Exception e 25 | */ 26 | public static String validate(Object obj) 27 | { 28 | Assert.notNull(obj, "参数为null"); 29 | // 校验结果 30 | String validateResult = null; 31 | // 获取类字段 32 | Field[] fields = obj.getClass().getDeclaredFields(); 33 | // 遍历pojo的字段进行校验 34 | for (Field field : fields) 35 | { 36 | try 37 | { 38 | validateResult = fieldValidate(obj, field); 39 | } 40 | catch (IllegalAccessException e) 41 | { 42 | e.printStackTrace(); 43 | validateResult = "校验过程出现异常"; 44 | } 45 | if (!StringUtils.isEmpty(validateResult)) 46 | { 47 | return validateResult; 48 | } 49 | } 50 | return validateResult; 51 | } 52 | 53 | 54 | /** 55 | * 遍历字段上的注解对指定注解进行校验. 56 | * 57 | * @param obj 参数 58 | * @param field 属性 59 | * @return 单个字段的检验结果 60 | * @throws Exception e 61 | */ 62 | private static String fieldValidate(Object obj, Field field) throws IllegalAccessException 63 | { 64 | String backVal = null; 65 | // 获取字段名称 66 | String fieldName = field.getName(); 67 | // 获取字段的值 68 | Object value = field.get(obj); 69 | // 获取字段上的注解 70 | Annotation[] annotations = field.getAnnotations(); 71 | // 校验结果 72 | field.setAccessible(true); 73 | 74 | for (Annotation an : annotations) 75 | { 76 | // 若扫描到Verification注解 77 | if (an.annotationType().getName().equals(Validation.class.getName())) 78 | { 79 | // 获取指定类型注解 80 | Validation column = field.getAnnotation(Validation.class); 81 | // 进行业务处理,校验 82 | backVal = businessValidate(column, value); 83 | if (!StringUtils.isEmpty(backVal)) 84 | { 85 | return backVal; 86 | } 87 | } 88 | } 89 | field.setAccessible(false); 90 | return backVal; 91 | } 92 | 93 | /** 94 | * 业务校验 95 | * 96 | * @param column 注解 97 | * @param value 字段值 98 | * @return 业务校验结果 99 | */ 100 | private static String businessValidate(Validation column, Object value) 101 | { 102 | String emptyVal; 103 | String limitVal; 104 | if (!StringUtils.isEmpty(emptyVal = mustEmptyValidate(column, value))) 105 | { 106 | return emptyVal; 107 | } 108 | else if (!StringUtils.isEmpty(limitVal = limitValueValidate(column, value))) 109 | { 110 | return limitVal; 111 | } 112 | else 113 | { 114 | return allowValueValidate(column, value); 115 | } 116 | } 117 | 118 | /** 119 | * 必须为空校验 120 | * 121 | * @param column 注解 122 | * @param value 字段值 123 | * @return 业务校验结果 124 | */ 125 | private static String mustEmptyValidate(Validation column, Object value) 126 | { 127 | if (column.mustEmpty() && null != value) 128 | { 129 | return column.limitMsg(); 130 | } 131 | else 132 | { 133 | return null; 134 | } 135 | } 136 | 137 | /** 138 | * 限制值校验 139 | * 140 | * @param column 注解 141 | * @param value 字段值 142 | * @return 业务校验结果 143 | */ 144 | private static String limitValueValidate(Validation column, Object value) 145 | { 146 | String[] limitArray = column.limitValue(); 147 | if (limitArray.length > 0) 148 | { 149 | value = String.valueOf(value); 150 | boolean result = Arrays.asList(limitArray).contains(value); 151 | if (result) 152 | { 153 | return column.limitMsg(); 154 | } 155 | else 156 | { 157 | return null; 158 | } 159 | } 160 | else 161 | { 162 | return null; 163 | } 164 | } 165 | 166 | /** 167 | * 允许值校验 168 | * 169 | * @param column 注解 170 | * @param value 字段值 171 | * @return 业务校验结果 172 | */ 173 | private static String allowValueValidate(Validation column, Object value) 174 | { 175 | String[] allowArray = column.allowValue(); 176 | if (allowArray.length > 0) 177 | { 178 | value = String.valueOf(value); 179 | boolean result = Arrays.asList(allowArray).contains(value); 180 | if (!result) 181 | { 182 | return column.limitMsg(); 183 | } 184 | else 185 | { 186 | return null; 187 | } 188 | } 189 | else 190 | { 191 | return null; 192 | } 193 | } 194 | } 195 | 196 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/util/DealSocket.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.util; 2 | 3 | 4 | import com.lance.api.business.pojo.model.EntryModel; 5 | import com.lance.api.business.pojo.model.ReturnModel; 6 | import com.lance.api.business.service.wrap.core.BaseServiceWrapper; 7 | import com.lance.api.business.service.wrap.core.ServiceWrapperContainer; 8 | import com.lance.api.common.base.model.Communication; 9 | import com.lance.api.common.constant.ResponseCode; 10 | import lombok.Data; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.slf4j.MDC; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.scheduling.annotation.Async; 15 | import org.springframework.stereotype.Component; 16 | import org.springframework.util.StringUtils; 17 | 18 | import java.io.BufferedInputStream; 19 | import java.io.BufferedOutputStream; 20 | import java.io.InputStream; 21 | import java.io.OutputStream; 22 | import java.net.Socket; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | *

socket业务分发类 28 | * 29 | * @author lance 30 | * @since 2018-10-15 31 | */ 32 | @Data 33 | @Slf4j 34 | @Component 35 | @SuppressWarnings("unchecked") 36 | public class DealSocket 37 | { 38 | /** 39 | * service包装类容器 40 | */ 41 | @Autowired 42 | private ServiceWrapperContainer serviceWrapperContainer; 43 | 44 | /** 45 | * 解析并处理报文 46 | * 47 | * @param socket 48 | * @throws Exception 49 | */ 50 | @Async 51 | public void analysisAndDealMsg(Socket socket) throws Exception 52 | { 53 | /* 54 | 1.获取socket数据 55 | */ 56 | InputStream input = socket.getInputStream(); 57 | OutputStream output = socket.getOutputStream(); 58 | BufferedInputStream bis = new BufferedInputStream(input); 59 | BufferedOutputStream bos = new BufferedOutputStream(output); 60 | byte[] buffer = new byte[36000]; 61 | bis.read(buffer); 62 | 63 | // 解析报文 64 | EntryModel entryModel = ComposeUtil.deSplit(new ByteDataBuffer(buffer)); 65 | if (entryModel == null) 66 | { 67 | noSignFlag(bos); 68 | return; 69 | } 70 | // 业务请求码 71 | String servCode = entryModel.getHeadModel().getServCode(); 72 | // 报文标识 73 | String msgId = entryModel.getHeadModel().getMsgId(); 74 | /* 75 | 2.业务处理 76 | */ 77 | MDC.put("logId", msgId); 78 | doBusiness(servCode, msgId, entryModel, bos); 79 | MDC.clear(); 80 | 81 | } 82 | 83 | /** 84 | * 处理业务(原生socket使用) 85 | * 86 | * @param servCode 87 | * @param msgId 88 | * @param entryModel 89 | * @param bos 90 | */ 91 | @Async 92 | public void doBusiness(String servCode, String msgId, EntryModel entryModel, BufferedOutputStream bos) 93 | { 94 | Map resultMap = null; 95 | try 96 | { 97 | if (StringUtils.isEmpty(servCode) || StringUtils.isEmpty(msgId)) 98 | { 99 | resultMap = Communication.getInstance().getFailedMap(ResponseCode._0000.getKey(), ResponseCode._0000.getValue()); 100 | } 101 | else 102 | { 103 | log.info("业务处理开始"); 104 | 105 | // 根据servCode查询所对应的service业务处理类 106 | BaseServiceWrapper baseServiceWrapper = serviceWrapperContainer.getService(servCode); 107 | // 或有业务存在servCode相同的情况,需加以判断是否存在servCode相同的情况 108 | if (baseServiceWrapper.hasSameService()) 109 | { 110 | // 根据servCode查询出所有servCode相同的service 111 | List baseServiceWrappers = serviceWrapperContainer.findSameService(servCode); 112 | for (BaseServiceWrapper bs : baseServiceWrappers) 113 | { 114 | if (bs.sameIsMyDo(entryModel)) 115 | { 116 | resultMap = bs.handle(entryModel); 117 | } 118 | } 119 | } 120 | else 121 | { 122 | resultMap = baseServiceWrapper.handle(entryModel); 123 | } 124 | log.info("业务处理完毕"); 125 | } 126 | } 127 | catch (Exception e) 128 | { 129 | log.error("业务处理发生异常:\n{}", e.getMessage()); 130 | e.printStackTrace(); 131 | resultMap = Communication.getInstance().getFailedMap(ResponseCode._0009.getKey(), ResponseCode._0009.getValue()); 132 | } 133 | finally 134 | { 135 | try 136 | { 137 | bos.write(ComposeUtil.doCanProcess(resultMap, servCode, msgId)); 138 | bos.flush(); 139 | } 140 | catch (Exception e) 141 | { 142 | e.printStackTrace(); 143 | } 144 | } 145 | } 146 | 147 | /** 148 | * 处理业务(netty使用) 149 | * 150 | * @param servCode 151 | * @param msgId 152 | * @param entryModel 153 | */ 154 | public ReturnModel doBusiness(String servCode, String msgId, EntryModel entryModel) 155 | { 156 | ReturnModel resultModel = new ReturnModel(); 157 | resultModel.setServCode(servCode); 158 | resultModel.setMsgId(msgId); 159 | try 160 | { 161 | if (StringUtils.isEmpty(servCode) || StringUtils.isEmpty(msgId)) 162 | { 163 | return resultModel.setMap(Communication.getInstance().getFailedMap(ResponseCode._0000.getKey(), ResponseCode._0000.getValue())); 164 | } 165 | log.info("业务处理开始"); 166 | 167 | // 根据servCode查询所对应的service业务处理类 168 | BaseServiceWrapper baseServiceWrapper = serviceWrapperContainer.getService(servCode); 169 | // 或有业务存在servCode相同的情况,需加以判断是否存在servCode相同的情况 170 | if (baseServiceWrapper.hasSameService()) 171 | { 172 | // 根据servCode查询出所有servCode相同的service 173 | List baseServiceWrappers = serviceWrapperContainer.findSameService(servCode); 174 | for (BaseServiceWrapper bs : baseServiceWrappers) 175 | { 176 | if (bs.sameIsMyDo(entryModel)) 177 | { 178 | resultModel.setMap(bs.handle(entryModel)); 179 | } 180 | } 181 | } 182 | else 183 | { 184 | resultModel.setMap(baseServiceWrapper.handle(entryModel)); 185 | } 186 | log.info("业务处理完毕"); 187 | } 188 | catch (Exception e) 189 | { 190 | log.error("业务处理发生异常:\n{}", e.getMessage()); 191 | e.printStackTrace(); 192 | resultModel.setMap(Communication.getInstance().getFailedMap(ResponseCode._0009.getKey(), ResponseCode._0009.getValue())); 193 | } 194 | return resultModel; 195 | } 196 | 197 | /** 198 | * 若无起始标记,则返回无标识信息 199 | * 200 | * @param bos 201 | */ 202 | public void noSignFlag(BufferedOutputStream bos) 203 | { 204 | Map resultMap = Communication.getInstance().getFailedMap(ResponseCode._0000.getKey(), ResponseCode._0000.getValue()); 205 | try 206 | { 207 | bos.write(ComposeUtil.doCanProcess(resultMap, "", "")); 208 | bos.flush(); 209 | bos.close(); 210 | } 211 | catch (Exception e) 212 | { 213 | e.printStackTrace(); 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/util/SftpUtil.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.util; 2 | 3 | 4 | import com.jcraft.jsch.*; 5 | import lombok.extern.slf4j.Slf4j; 6 | 7 | import java.io.*; 8 | import java.util.List; 9 | import java.util.Properties; 10 | import java.util.Vector; 11 | 12 | /** 13 | * sftp连接工具 14 | * 15 | * @author lance 16 | */ 17 | @Slf4j 18 | public class SftpUtil 19 | { 20 | private ChannelSftp sftp = null; 21 | private Channel channel = null; 22 | private Session session = null; 23 | 24 | public SftpUtil() 25 | { 26 | } 27 | 28 | public void connect(String host, int port, String userName, String password, String path) throws Exception 29 | { 30 | this.connectServer(host, port, userName, password, path); 31 | } 32 | 33 | private boolean connectServer(String hostName, int port, String userName, String password, String path) throws Exception 34 | { 35 | try 36 | { 37 | JSch jSch = new JSch(); 38 | this.session = jSch.getSession(userName, hostName, port); 39 | this.session.setPassword(password); 40 | this.session.setConfig(this.getSshConfig()); 41 | this.session.connect(); 42 | this.channel = this.session.openChannel("sftp"); 43 | this.channel.connect(); 44 | this.sftp = (ChannelSftp) this.channel; 45 | if (path.length() != 0) 46 | { 47 | this.sftp.cd(path); 48 | } 49 | 50 | return true; 51 | } 52 | catch (JSchException e) 53 | { 54 | log.info("SSH方式连接FTP服务器时有JSchException异常!"); 55 | e.printStackTrace(); 56 | throw e; 57 | } 58 | } 59 | 60 | private Properties getSshConfig() throws Exception 61 | { 62 | Properties sshConfig = null; 63 | 64 | try 65 | { 66 | sshConfig = new Properties(); 67 | sshConfig.put("StrictHostKeyChecking", "no"); 68 | return sshConfig; 69 | } 70 | catch (Exception e) 71 | { 72 | throw e; 73 | } 74 | } 75 | 76 | public boolean downloadFile(String remoteFilename, String localFilename) throws SftpException, IOException, Exception 77 | { 78 | FileOutputStream output = null; 79 | boolean success = false; 80 | 81 | boolean result; 82 | try 83 | { 84 | File localFile = new File(localFilename); 85 | if (!localFile.exists()) 86 | { 87 | log.info("本地不存在待下载文件: " + localFilename + " ,将创建一个新文件!"); 88 | localFile.createNewFile(); 89 | } 90 | 91 | output = new FileOutputStream(localFile); 92 | this.sftp.get(remoteFilename, output); 93 | success = true; 94 | log.info("成功接收文件,本地路径:" + localFilename); 95 | return success; 96 | } 97 | catch (SftpException e) 98 | { 99 | log.info("接收文件时有SftpException异常!"); 100 | e.printStackTrace(); 101 | result = success; 102 | } 103 | catch (IOException e) 104 | { 105 | log.info("接收文件时有I/O异常!"); 106 | e.printStackTrace(); 107 | result = success; 108 | } 109 | finally 110 | { 111 | try 112 | { 113 | if (null != output) 114 | { 115 | output.close(); 116 | } 117 | 118 | this.disconnect(); 119 | } 120 | catch (IOException e) 121 | { 122 | log.info("关闭文件时出错!"); 123 | e.printStackTrace(); 124 | } 125 | 126 | } 127 | return result; 128 | } 129 | 130 | public boolean uploadFile(String remoteFilename, String localFileName) throws SftpException, Exception 131 | { 132 | boolean success = false; 133 | FileInputStream fis = null; 134 | 135 | try 136 | { 137 | File localFile = new File(localFileName); 138 | fis = new FileInputStream(localFile); 139 | this.sftp.put(fis, remoteFilename); 140 | success = true; 141 | log.info("成功发送文件,本地路径:" + localFileName); 142 | } 143 | catch (SftpException e) 144 | { 145 | log.info("发送文件时有SftpException异常!"); 146 | e.printStackTrace(); 147 | throw e; 148 | } 149 | catch (Exception e) 150 | { 151 | log.info("发送文件时有异常!"); 152 | e.printStackTrace(); 153 | throw e; 154 | } 155 | finally 156 | { 157 | try 158 | { 159 | if (null != fis) 160 | { 161 | fis.close(); 162 | } 163 | 164 | this.disconnect(); 165 | } 166 | catch (IOException e) 167 | { 168 | log.info("关闭文件时出错!"); 169 | e.printStackTrace(); 170 | } 171 | 172 | } 173 | 174 | return success; 175 | } 176 | 177 | public boolean uploadFile(String remotePath, String remoteFilename, InputStream input) throws Exception 178 | { 179 | boolean success = false; 180 | 181 | try 182 | { 183 | if (null != remotePath && remotePath.trim() != "") 184 | { 185 | this.sftp.cd(remotePath); 186 | } 187 | 188 | this.sftp.put(input, remoteFilename); 189 | success = true; 190 | } 191 | catch (SftpException e) 192 | { 193 | log.info("发送文件时有SftpException异常!"); 194 | e.printStackTrace(); 195 | log.info(e.getMessage()); 196 | throw e; 197 | } 198 | catch (Exception e) 199 | { 200 | log.info("发送文件时有异常!"); 201 | e.printStackTrace(); 202 | throw e; 203 | } 204 | finally 205 | { 206 | try 207 | { 208 | if (null != input) 209 | { 210 | input.close(); 211 | } 212 | 213 | this.disconnect(); 214 | } 215 | catch (IOException e) 216 | { 217 | log.info("关闭文件时出错!"); 218 | e.printStackTrace(); 219 | } 220 | 221 | } 222 | 223 | return success; 224 | } 225 | 226 | public boolean deleteFile(String remoteFilename) throws Exception 227 | { 228 | boolean success = false; 229 | 230 | boolean result; 231 | try 232 | { 233 | this.sftp.rm(remoteFilename); 234 | log.info("删除远程文件" + remoteFilename + "成功!"); 235 | success = true; 236 | return success; 237 | } 238 | catch (SftpException e) 239 | { 240 | log.info("删除文件时有SftpException异常!"); 241 | e.printStackTrace(); 242 | log.info(e.getMessage()); 243 | result = success; 244 | } 245 | catch (Exception e) 246 | { 247 | log.info("删除文件时有异常!"); 248 | log.info(e.getMessage()); 249 | result = success; 250 | } 251 | finally 252 | { 253 | this.disconnect(); 254 | } 255 | return result; 256 | } 257 | 258 | public List listFiles(String directory) throws Exception 259 | { 260 | Vector list = null; 261 | 262 | try 263 | { 264 | list = this.sftp.ls(directory); 265 | } 266 | catch (SftpException e) 267 | { 268 | throw e; 269 | } 270 | finally 271 | { 272 | this.disconnect(); 273 | } 274 | 275 | return list; 276 | } 277 | 278 | private void disconnect() throws Exception 279 | { 280 | try 281 | { 282 | if (this.sftp.isConnected()) 283 | { 284 | this.sftp.disconnect(); 285 | } 286 | 287 | if (this.channel.isConnected()) 288 | { 289 | this.channel.disconnect(); 290 | } 291 | 292 | if (this.session.isConnected()) 293 | { 294 | this.session.disconnect(); 295 | } 296 | 297 | } 298 | catch (Exception e) 299 | { 300 | throw e; 301 | } 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /src/test/java/com/sslsocketclient/ByteDataBuffer.java: -------------------------------------------------------------------------------- 1 | package com.sslsocketclient; 2 | 3 | 4 | import java.io.UnsupportedEncodingException; 5 | 6 | 7 | public class ByteDataBuffer 8 | { 9 | private static int INCREASE_DATA_SIZE = 256; 10 | private boolean inBigEndian; 11 | private byte dataBuffer[]; 12 | private int pos; 13 | private int dataSize; 14 | private String encoding; 15 | private char defaultFillChar; 16 | 17 | public ByteDataBuffer() 18 | { 19 | this(INCREASE_DATA_SIZE); 20 | } 21 | 22 | public ByteDataBuffer(int size) 23 | { 24 | inBigEndian = true; 25 | pos = 0; 26 | encoding = "UTF-8"; 27 | dataBuffer = new byte[size]; 28 | dataSize = 0; 29 | } 30 | 31 | public ByteDataBuffer(byte data[]) 32 | { 33 | inBigEndian = true; 34 | pos = 0; 35 | encoding = "UTF-8"; 36 | if (data != null) 37 | { 38 | dataBuffer = data; 39 | dataSize = data.length; 40 | } 41 | else 42 | { 43 | dataBuffer = new byte[INCREASE_DATA_SIZE]; 44 | dataSize = 0; 45 | } 46 | } 47 | 48 | public void ensureCapacity(int minCapacity) throws Exception 49 | { 50 | if (dataBuffer.length < minCapacity) 51 | { 52 | int nextBufSize = INCREASE_DATA_SIZE * (minCapacity / INCREASE_DATA_SIZE + 1); 53 | byte data[] = new byte[nextBufSize]; 54 | System.arraycopy(dataBuffer, 0, data, 0, dataBuffer.length); 55 | dataBuffer = data; 56 | } 57 | } 58 | 59 | public void writeBytes(byte data[]) throws Exception 60 | { 61 | writeBytes(data, 0, data.length); 62 | } 63 | 64 | public void writeBytes(byte data[], int srcPos, int length) throws Exception 65 | { 66 | if (data == null || length <= 0) 67 | { 68 | return; 69 | } 70 | if (srcPos + length > data.length) 71 | { 72 | length = data.length - srcPos; 73 | } 74 | ensureCapacity(pos + length); 75 | System.arraycopy(data, srcPos, dataBuffer, pos, length); 76 | pos += length; 77 | } 78 | 79 | public void writeInt8(byte data) throws Exception 80 | { 81 | ensureCapacity(pos + 1); 82 | dataBuffer[pos] = data; 83 | pos++; 84 | } 85 | 86 | public void writeFillerBytes(byte data, int length) throws Exception 87 | { 88 | ensureCapacity(pos + length); 89 | for (int j = 0; j < length; j++) 90 | { 91 | dataBuffer[pos] = data; 92 | pos++; 93 | } 94 | 95 | } 96 | 97 | public void writeInt16(int i) throws Exception 98 | { 99 | ensureCapacity(pos + 2); 100 | if (inBigEndian) 101 | { 102 | dataBuffer[pos] = (byte) (i >>> 8 & 255); 103 | dataBuffer[pos + 1] = (byte) (i & 255); 104 | } 105 | else 106 | { 107 | dataBuffer[pos] = (byte) (i & 255); 108 | dataBuffer[pos + 1] = (byte) (i >>> 8 & 255); 109 | } 110 | pos += 2; 111 | } 112 | 113 | public void writeInt32(int i) throws Exception 114 | { 115 | ensureCapacity(pos + 4); 116 | if (inBigEndian) 117 | { 118 | dataBuffer[pos] = (byte) (i >>> 24 & 255); 119 | dataBuffer[pos + 1] = (byte) (i >>> 16 & 255); 120 | dataBuffer[pos + 2] = (byte) (i >>> 8 & 255); 121 | dataBuffer[pos + 3] = (byte) (i & 255); 122 | } 123 | else 124 | { 125 | dataBuffer[pos] = (byte) (i & 255); 126 | dataBuffer[pos + 1] = (byte) (i >>> 8 & 255); 127 | dataBuffer[pos + 2] = (byte) (i >>> 16 & 255); 128 | dataBuffer[pos + 3] = (byte) (i >>> 24 & 255); 129 | } 130 | pos += 4; 131 | } 132 | 133 | public void writeString(String s) throws Exception 134 | { 135 | if (s == null) 136 | { 137 | writeInt16(-1); 138 | return; 139 | } 140 | else 141 | { 142 | byte data[] = s.getBytes(encoding); 143 | writeInt16(data.length); 144 | writeBytes(data, 0, data.length); 145 | return; 146 | } 147 | } 148 | 149 | public void writeString(String s, int size) throws Exception 150 | { 151 | writeString(s, size, defaultFillChar); 152 | } 153 | 154 | public void writeString(String s, int size, char fillChar) throws Exception 155 | { 156 | if (s == null) 157 | { 158 | s = ""; 159 | } 160 | byte data[] = s.getBytes(encoding); 161 | if (data.length >= size) 162 | { 163 | writeBytes(data, 0, size); 164 | } 165 | else 166 | { 167 | writeBytes(data, 0, data.length); 168 | writeFillerBytes((byte) (fillChar & 255), size - data.length); 169 | } 170 | } 171 | 172 | public int readBytes(byte data[]) throws Exception 173 | { 174 | return readBytes(data, 0, data.length); 175 | } 176 | 177 | public int readBytes(byte data[], int destPos, int length) throws Exception 178 | { 179 | if (length > dataBuffer.length - pos) 180 | { 181 | length = dataBuffer.length - pos; 182 | } 183 | if (length > 0) 184 | { 185 | System.arraycopy(dataBuffer, pos, data, destPos, length); 186 | } 187 | pos += length; 188 | return length; 189 | } 190 | 191 | public int readInt32() throws Exception 192 | { 193 | int i; 194 | if (inBigEndian) 195 | { 196 | i = ((dataBuffer[pos] & 255) << 24) + ((dataBuffer[pos + 1] & 255) << 16) + ((dataBuffer[pos + 2] & 255) << 8) + (dataBuffer[pos + 3] & 255); 197 | } 198 | else 199 | { 200 | i = (dataBuffer[pos] & 255) + ((dataBuffer[pos + 1] & 255) << 8) + ((dataBuffer[pos + 2] & 255) << 16) + ((dataBuffer[pos + 3] & 255) << 24); 201 | } 202 | pos += 4; 203 | return i; 204 | } 205 | 206 | public byte readInt8() throws Exception 207 | { 208 | if (dataBuffer.length - pos > 0) 209 | { 210 | byte result = dataBuffer[pos]; 211 | pos++; 212 | return result; 213 | } 214 | else 215 | { 216 | throw new Exception("no Data"); 217 | } 218 | } 219 | 220 | public byte[] getBytes() 221 | { 222 | byte data[] = new byte[getDataSize()]; 223 | System.arraycopy(dataBuffer, 0, data, 0, data.length); 224 | return data; 225 | } 226 | 227 | public short readInt16() throws Exception 228 | { 229 | short word0; 230 | if (inBigEndian) 231 | { 232 | word0 = (short) (((dataBuffer[pos] & 255) << 8) + (dataBuffer[pos + 1] & 255)); 233 | } 234 | else 235 | { 236 | word0 = (short) ((dataBuffer[pos] & 255) + ((dataBuffer[pos + 1] & 255) << 8)); 237 | } 238 | pos += 2; 239 | return word0; 240 | } 241 | 242 | public String readString() throws Exception 243 | { 244 | String result = null; 245 | int strLen = readInt16(); 246 | if (strLen > 0) 247 | { 248 | result = new String(dataBuffer, pos, strLen, encoding); 249 | pos += strLen; 250 | } 251 | if (strLen == 0) 252 | { 253 | return ""; 254 | } 255 | else 256 | { 257 | return result; 258 | } 259 | } 260 | 261 | public String readString(int size) throws Exception 262 | { 263 | return readString(size, defaultFillChar); 264 | } 265 | 266 | public String readString(int size, char fillByte) throws Exception 267 | { 268 | int strLen = size; 269 | if (strLen > 0) 270 | { 271 | for (; strLen > 0 && dataBuffer[(pos + strLen) - 1] == fillByte; strLen--) 272 | ; 273 | String result = new String(dataBuffer, pos, strLen, encoding); 274 | pos += size; 275 | return result; 276 | } 277 | else 278 | { 279 | return null; 280 | } 281 | } 282 | 283 | public int getDataSize() 284 | { 285 | if (pos > dataSize) 286 | { 287 | dataSize = pos; 288 | } 289 | return dataSize; 290 | } 291 | 292 | public char getDefaultFillChar() 293 | { 294 | return defaultFillChar; 295 | } 296 | 297 | public String getEncoding() 298 | { 299 | return encoding; 300 | } 301 | 302 | public boolean isInBigEndian() 303 | { 304 | return inBigEndian; 305 | } 306 | 307 | public int getPos() 308 | { 309 | return pos; 310 | } 311 | 312 | public void setDefaultFillChar(char defaultFillChar) 313 | { 314 | this.defaultFillChar = defaultFillChar; 315 | } 316 | 317 | public void setEncoding(String encoding) 318 | { 319 | this.encoding = encoding; 320 | } 321 | 322 | public void setInBigEndian(boolean inBigEndian) 323 | { 324 | this.inBigEndian = inBigEndian; 325 | } 326 | 327 | public void setPos(int pos) 328 | { 329 | this.pos = pos; 330 | } 331 | 332 | public byte[] getDataBuffer() 333 | { 334 | return dataBuffer; 335 | } 336 | 337 | public void reset() 338 | { 339 | dataSize = 0; 340 | pos = 0; 341 | } 342 | 343 | public boolean hasData() 344 | { 345 | return pos < dataSize; 346 | } 347 | 348 | public String readCString() throws Exception 349 | { 350 | byte data[] = getDataBuffer(); 351 | int endPos = -1; 352 | int i = pos; 353 | do 354 | { 355 | if (i >= data.length) 356 | { 357 | break; 358 | } 359 | if (data[i] == 0) 360 | { 361 | endPos = i; 362 | break; 363 | } 364 | i++; 365 | } while (true); 366 | if (endPos < 0) 367 | { 368 | endPos = data.length; 369 | } 370 | String s = new String(data, pos, endPos - pos, encoding); 371 | pos = endPos + 1; 372 | return s; 373 | } 374 | 375 | public void writeCString(String cs) throws Exception 376 | { 377 | if (cs == null) 378 | { 379 | cs = ""; 380 | } 381 | byte data[] = cs.getBytes(encoding); 382 | int pos = -1; 383 | int i = 0; 384 | do 385 | { 386 | if (i >= data.length) 387 | { 388 | break; 389 | } 390 | if (data[i] == 0) 391 | { 392 | pos = i; 393 | break; 394 | } 395 | i++; 396 | } while (true); 397 | if (pos >= 0) 398 | { 399 | writeBytes(data, 0, pos + 1); 400 | } 401 | else 402 | { 403 | writeBytes(data, 0, data.length); 404 | writeInt8((byte) 0); 405 | } 406 | } 407 | 408 | public static String getLen(String text, int needlen) 409 | { 410 | if (text != null) 411 | { 412 | int len; 413 | try 414 | { 415 | len = text.getBytes("utf-8").length + 39; 416 | // ����Ҫ 417 | 418 | String lenStr = String.valueOf(len); 419 | StringBuffer sb = new StringBuffer(lenStr); 420 | while (sb.length() < needlen) 421 | { 422 | sb.insert(0, "0"); 423 | } 424 | return sb.toString(); 425 | } 426 | catch (UnsupportedEncodingException e) 427 | { 428 | e.printStackTrace(); 429 | } 430 | } 431 | return null; 432 | } 433 | 434 | } 435 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/business/util/ByteDataBuffer.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.business.util; 2 | 3 | 4 | import java.io.UnsupportedEncodingException; 5 | 6 | /** 7 | * byte工具类 8 | * 9 | * @author lance 10 | * @since 2018-10-12 11 | */ 12 | public class ByteDataBuffer 13 | { 14 | /** 15 | * 缓存大小 16 | */ 17 | private static int INCREASE_DATA_SIZE = 256; 18 | /** 19 | * 数字高低位 标示 20 | */ 21 | private boolean inBigEndian; 22 | private byte dataBuffer[]; 23 | private int pos; 24 | private int dataSize; 25 | private String encoding; 26 | private char defaultFillChar; 27 | 28 | public ByteDataBuffer() 29 | { 30 | this(INCREASE_DATA_SIZE); 31 | } 32 | 33 | public ByteDataBuffer(int size) 34 | { 35 | inBigEndian = true; 36 | pos = 0; 37 | encoding = "UTF-8"; 38 | dataBuffer = new byte[size]; 39 | dataSize = 0; 40 | } 41 | 42 | public ByteDataBuffer(byte data[]) 43 | { 44 | inBigEndian = true; 45 | pos = 0; 46 | encoding = "UTF-8"; 47 | if (data != null) 48 | { 49 | dataBuffer = data; 50 | dataSize = data.length; 51 | } 52 | else 53 | { 54 | dataBuffer = new byte[INCREASE_DATA_SIZE]; 55 | dataSize = 0; 56 | } 57 | } 58 | 59 | public void ensureCapacity(int minCapacity) throws Exception 60 | { 61 | if (dataBuffer.length < minCapacity) 62 | { 63 | int nextBufSize = INCREASE_DATA_SIZE * (minCapacity / INCREASE_DATA_SIZE + 1); 64 | byte data[] = new byte[nextBufSize]; 65 | System.arraycopy(dataBuffer, 0, data, 0, dataBuffer.length); 66 | dataBuffer = data; 67 | } 68 | } 69 | 70 | public void writeBytes(byte data[]) throws Exception 71 | { 72 | writeBytes(data, 0, data.length); 73 | } 74 | 75 | public void writeBytes(byte data[], int srcPos, int length) throws Exception 76 | { 77 | if (data == null || length <= 0) 78 | { 79 | return; 80 | } 81 | if (srcPos + length > data.length) 82 | { 83 | length = data.length - srcPos; 84 | } 85 | ensureCapacity(pos + length); 86 | System.arraycopy(data, srcPos, dataBuffer, pos, length); 87 | pos += length; 88 | } 89 | 90 | public void writeInt8(byte data) throws Exception 91 | { 92 | ensureCapacity(pos + 1); 93 | dataBuffer[pos] = data; 94 | pos++; 95 | } 96 | 97 | public void writeFillerBytes(byte data, int length) throws Exception 98 | { 99 | ensureCapacity(pos + length); 100 | for (int j = 0; j < length; j++) 101 | { 102 | dataBuffer[pos] = data; 103 | pos++; 104 | } 105 | 106 | } 107 | 108 | public void writeInt16(int i) throws Exception 109 | { 110 | ensureCapacity(pos + 2); 111 | if (inBigEndian) 112 | { 113 | dataBuffer[pos] = (byte) (i >>> 8 & 255); 114 | dataBuffer[pos + 1] = (byte) (i & 255); 115 | } 116 | else 117 | { 118 | dataBuffer[pos] = (byte) (i & 255); 119 | dataBuffer[pos + 1] = (byte) (i >>> 8 & 255); 120 | } 121 | pos += 2; 122 | } 123 | 124 | public void writeInt32(int i) throws Exception 125 | { 126 | ensureCapacity(pos + 4); 127 | if (inBigEndian) 128 | { 129 | dataBuffer[pos] = (byte) (i >>> 24 & 255); 130 | dataBuffer[pos + 1] = (byte) (i >>> 16 & 255); 131 | dataBuffer[pos + 2] = (byte) (i >>> 8 & 255); 132 | dataBuffer[pos + 3] = (byte) (i & 255); 133 | } 134 | else 135 | { 136 | dataBuffer[pos] = (byte) (i & 255); 137 | dataBuffer[pos + 1] = (byte) (i >>> 8 & 255); 138 | dataBuffer[pos + 2] = (byte) (i >>> 16 & 255); 139 | dataBuffer[pos + 3] = (byte) (i >>> 24 & 255); 140 | } 141 | pos += 4; 142 | } 143 | 144 | public void writeString(String s) throws Exception 145 | { 146 | if (s == null) 147 | { 148 | writeInt16(-1); 149 | return; 150 | } 151 | else 152 | { 153 | byte data[] = s.getBytes(encoding); 154 | writeInt16(data.length); 155 | writeBytes(data, 0, data.length); 156 | return; 157 | } 158 | } 159 | 160 | public void writeString(String s, int size) throws Exception 161 | { 162 | writeString(s, size, defaultFillChar); 163 | } 164 | 165 | public void writeString(String s, int size, char fillChar) throws Exception 166 | { 167 | if (s == null) 168 | { 169 | s = ""; 170 | } 171 | byte data[] = s.getBytes(encoding); 172 | if (data.length >= size) 173 | { 174 | writeBytes(data, 0, size); 175 | } 176 | else 177 | { 178 | writeBytes(data, 0, data.length); 179 | writeFillerBytes((byte) (fillChar & 255), size - data.length); 180 | } 181 | } 182 | 183 | public int readBytes(byte data[]) throws Exception 184 | { 185 | return readBytes(data, 0, data.length); 186 | } 187 | 188 | public int readBytes(byte data[], int destPos, int length) throws Exception 189 | { 190 | if (length > dataBuffer.length - pos) 191 | { 192 | length = dataBuffer.length - pos; 193 | } 194 | if (length > 0) 195 | { 196 | System.arraycopy(dataBuffer, pos, data, destPos, length); 197 | } 198 | pos += length; 199 | return length; 200 | } 201 | 202 | public int readInt32() throws Exception 203 | { 204 | int i; 205 | if (inBigEndian) 206 | { 207 | i = ((dataBuffer[pos] & 255) << 24) + ((dataBuffer[pos + 1] & 255) << 16) + ((dataBuffer[pos + 2] & 255) << 8) + (dataBuffer[pos + 3] & 255); 208 | } 209 | else 210 | { 211 | i = (dataBuffer[pos] & 255) + ((dataBuffer[pos + 1] & 255) << 8) + ((dataBuffer[pos + 2] & 255) << 16) + ((dataBuffer[pos + 3] & 255) << 24); 212 | } 213 | pos += 4; 214 | return i; 215 | } 216 | 217 | public byte readInt8() throws Exception 218 | { 219 | if (dataBuffer.length - pos > 0) 220 | { 221 | byte result = dataBuffer[pos]; 222 | pos++; 223 | return result; 224 | } 225 | else 226 | { 227 | throw new Exception("no Data"); 228 | } 229 | } 230 | 231 | public byte[] getBytes() 232 | { 233 | byte data[] = new byte[getDataSize()]; 234 | System.arraycopy(dataBuffer, 0, data, 0, data.length); 235 | return data; 236 | } 237 | 238 | public short readInt16() throws Exception 239 | { 240 | short word0; 241 | if (inBigEndian) 242 | { 243 | word0 = (short) (((dataBuffer[pos] & 255) << 8) + (dataBuffer[pos + 1] & 255)); 244 | } 245 | else 246 | { 247 | word0 = (short) ((dataBuffer[pos] & 255) + ((dataBuffer[pos + 1] & 255) << 8)); 248 | } 249 | pos += 2; 250 | return word0; 251 | } 252 | 253 | public String readString() throws Exception 254 | { 255 | String result = null; 256 | int strLen = readInt16(); 257 | if (strLen > 0) 258 | { 259 | result = new String(dataBuffer, pos, strLen, encoding); 260 | pos += strLen; 261 | } 262 | if (strLen == 0) 263 | { 264 | return ""; 265 | } 266 | else 267 | { 268 | return result; 269 | } 270 | } 271 | 272 | public String readString(int size) throws Exception 273 | { 274 | return readString(size, defaultFillChar); 275 | } 276 | 277 | public String readString(int size, char fillByte) throws Exception 278 | { 279 | int strLen = size; 280 | if (strLen > 0) 281 | { 282 | for (; strLen > 0 && dataBuffer[(pos + strLen) - 1] == fillByte; strLen--) 283 | ; 284 | String result = new String(dataBuffer, pos, strLen, encoding); 285 | pos += size; 286 | return result; 287 | } 288 | else 289 | { 290 | return null; 291 | } 292 | } 293 | 294 | public int getDataSize() 295 | { 296 | if (pos > dataSize) 297 | { 298 | dataSize = pos; 299 | } 300 | return dataSize; 301 | } 302 | 303 | public char getDefaultFillChar() 304 | { 305 | return defaultFillChar; 306 | } 307 | 308 | public String getEncoding() 309 | { 310 | return encoding; 311 | } 312 | 313 | public boolean isInBigEndian() 314 | { 315 | return inBigEndian; 316 | } 317 | 318 | public int getPos() 319 | { 320 | return pos; 321 | } 322 | 323 | public void setDefaultFillChar(char defaultFillChar) 324 | { 325 | this.defaultFillChar = defaultFillChar; 326 | } 327 | 328 | public void setEncoding(String encoding) 329 | { 330 | this.encoding = encoding; 331 | } 332 | 333 | public void setInBigEndian(boolean inBigEndian) 334 | { 335 | this.inBigEndian = inBigEndian; 336 | } 337 | 338 | public void setPos(int pos) 339 | { 340 | this.pos = pos; 341 | } 342 | 343 | public byte[] getDataBuffer() 344 | { 345 | return dataBuffer; 346 | } 347 | 348 | public void reset() 349 | { 350 | dataSize = 0; 351 | pos = 0; 352 | } 353 | 354 | public boolean hasData() 355 | { 356 | return pos < dataSize; 357 | } 358 | 359 | public String readCString() throws Exception 360 | { 361 | byte data[] = getDataBuffer(); 362 | int endPos = -1; 363 | int i = pos; 364 | do 365 | { 366 | if (i >= data.length) 367 | { 368 | break; 369 | } 370 | if (data[i] == 0) 371 | { 372 | endPos = i; 373 | break; 374 | } 375 | i++; 376 | } while (true); 377 | if (endPos < 0) 378 | { 379 | endPos = data.length; 380 | } 381 | String s = new String(data, pos, endPos - pos, encoding); 382 | pos = endPos + 1; 383 | return s; 384 | } 385 | 386 | public void writeCString(String cs) throws Exception 387 | { 388 | if (cs == null) 389 | { 390 | cs = ""; 391 | } 392 | byte data[] = cs.getBytes(encoding); 393 | int pos = -1; 394 | int i = 0; 395 | do 396 | { 397 | if (i >= data.length) 398 | { 399 | break; 400 | } 401 | if (data[i] == 0) 402 | { 403 | pos = i; 404 | break; 405 | } 406 | i++; 407 | } while (true); 408 | if (pos >= 0) 409 | { 410 | writeBytes(data, 0, pos + 1); 411 | } 412 | else 413 | { 414 | writeBytes(data, 0, data.length); 415 | writeInt8((byte) 0); 416 | } 417 | } 418 | 419 | /** 420 | * 计算报文长度,不足四位左补零 421 | * 422 | * @param text 报文信息 423 | * @param needlen 报文长度规定的字符数 424 | * @return 425 | */ 426 | public static String getLen(String text, int needlen) 427 | { 428 | if (text != null) 429 | { 430 | int len; 431 | try 432 | { 433 | // serverCode和token长度 434 | len = text.getBytes("utf-8").length + 39; 435 | // 看需要 436 | 437 | String lenStr = String.valueOf(len); 438 | StringBuffer sb = new StringBuffer(lenStr); 439 | while (sb.length() < needlen) 440 | { 441 | sb.insert(0, "0"); 442 | } 443 | return sb.toString(); 444 | } 445 | catch (UnsupportedEncodingException e) 446 | { 447 | e.printStackTrace(); 448 | } 449 | } 450 | return null; 451 | } 452 | } 453 | -------------------------------------------------------------------------------- /src/main/java/com/lance/api/common/base/dao/BaseDao.java: -------------------------------------------------------------------------------- 1 | package com.lance.api.common.base.dao; 2 | 3 | import lombok.Data; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.dao.DataAccessException; 7 | import org.springframework.dao.EmptyResultDataAccessException; 8 | import org.springframework.jdbc.core.*; 9 | import org.springframework.stereotype.Repository; 10 | 11 | import java.sql.ResultSet; 12 | import java.sql.SQLException; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * 该类是基类的dao 18 | */ 19 | @Repository 20 | @Data 21 | @Slf4j 22 | @SuppressWarnings({"rawtypes", "unchecked"}) 23 | public class BaseDao 24 | { 25 | @Autowired 26 | private JdbcTemplate jdbcTemplate; 27 | 28 | /** 29 | * 执行Sql语句进行数据修改 30 | */ 31 | public void execute(String sql) throws DataAccessException 32 | { 33 | this.jdbcTemplate.execute(sql); 34 | } 35 | 36 | /** 37 | * 查询Sql,返回double 38 | * 39 | * @param sql 40 | * @return 41 | */ 42 | public double queryForDouble(String sql) throws DataAccessException 43 | { 44 | double backVal = 0.0; 45 | try 46 | { 47 | Number number = (Number) this.jdbcTemplate.queryForObject(sql, Double.class); 48 | backVal = (number != null ? number.doubleValue() : 0.0); 49 | } 50 | catch (DataAccessException dataAccessException) 51 | { 52 | throw dataAccessException; 53 | } 54 | return backVal; 55 | } 56 | 57 | /** 58 | * 查询double 59 | * 60 | * @param sql 预编译带?的sql 61 | * @param args 参数数组 62 | * @return double 63 | */ 64 | public double queryForDouble(String sql, Object[] args) throws DataAccessException 65 | { 66 | double backVal = 0.0; 67 | try 68 | { 69 | Number number = (Number) this.jdbcTemplate.queryForObject(sql, args, Double.class); 70 | backVal = (number != null ? number.doubleValue() : 0.0); 71 | } 72 | catch (DataAccessException dataAccessException) 73 | { 74 | throw dataAccessException; 75 | } 76 | return backVal; 77 | } 78 | 79 | /** 80 | * 查询double 81 | * 82 | * @param sql 预编译带?的sql 83 | * @param args 参数数组 84 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 85 | * @return double 86 | */ 87 | public double queryForDouble(String sql, Object[] args, int[] argTypes) throws DataAccessException 88 | { 89 | double backVal = 0.0; 90 | try 91 | { 92 | Number number = (Number) this.jdbcTemplate.queryForObject(sql, args, argTypes, Double.class); 93 | backVal = (number != null ? number.doubleValue() : 0.0); 94 | } 95 | catch (DataAccessException dataAccessException) 96 | { 97 | throw dataAccessException; 98 | } 99 | return backVal; 100 | } 101 | 102 | /** 103 | * 查询Sql,返回float 104 | * 105 | * @param sql 106 | * @return 107 | */ 108 | public float queryForFloat(String sql) throws DataAccessException 109 | { 110 | float backVal = 0; 111 | try 112 | { 113 | Number number = (Number) this.jdbcTemplate.queryForObject(sql, Float.class); 114 | backVal = (number != null ? number.floatValue() : 0); 115 | } 116 | catch (DataAccessException dataAccessException) 117 | { 118 | throw dataAccessException; 119 | } 120 | return backVal; 121 | } 122 | 123 | /** 124 | * 查询float 125 | * 126 | * @param sql 预编译带?的sql 127 | * @param args 参数数组 128 | * @return 129 | */ 130 | public float queryForFloat(String sql, Object[] args) throws DataAccessException 131 | { 132 | float backVal = 0; 133 | try 134 | { 135 | Number number = (Number) this.jdbcTemplate.queryForObject(sql, args, Float.class); 136 | backVal = (number != null ? number.floatValue() : 0); 137 | } 138 | catch (DataAccessException dataAccessException) 139 | { 140 | throw dataAccessException; 141 | } 142 | return backVal; 143 | } 144 | 145 | /** 146 | * 查询float 147 | * 148 | * @param sql 预编译带?的sql 149 | * @param args 参数数组 150 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 151 | * @return 152 | */ 153 | public float queryForFloat(String sql, Object[] args, int[] argTypes) throws DataAccessException 154 | { 155 | float backVal = 0; 156 | try 157 | { 158 | Number number = (Number) this.jdbcTemplate.queryForObject(sql, args, argTypes, Float.class); 159 | backVal = (number != null ? number.floatValue() : 0); 160 | } 161 | catch (DataAccessException dataAccessException) 162 | { 163 | throw dataAccessException; 164 | } 165 | return backVal; 166 | } 167 | 168 | /** 169 | * 查询Sql,返回int 170 | */ 171 | public int queryForInt(String sql) throws DataAccessException 172 | { 173 | int backVal = 0; 174 | try 175 | { 176 | Integer temBack = this.jdbcTemplate.queryForObject(sql, Integer.class); 177 | if (null != temBack) 178 | { 179 | backVal = temBack; 180 | } 181 | } 182 | catch (DataAccessException dataAccessException) 183 | { 184 | throw dataAccessException; 185 | } 186 | return backVal; 187 | } 188 | 189 | /** 190 | * 查询int 191 | * 192 | * @param sql 预编译带?的sql 193 | * @param args 参数数组 194 | * @return int 195 | */ 196 | public int queryForInt(String sql, Object[] args) throws DataAccessException 197 | { 198 | int backVal = 0; 199 | try 200 | { 201 | Integer temBack = this.jdbcTemplate.queryForObject(sql, args, Integer.class); 202 | if (null != temBack) 203 | { 204 | backVal = temBack; 205 | } 206 | } 207 | catch (DataAccessException dataAccessException) 208 | { 209 | throw dataAccessException; 210 | } 211 | return backVal; 212 | } 213 | 214 | /** 215 | * 查询int 216 | * 217 | * @param sql 预编译带?的sql 218 | * @param args 参数数组 219 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 220 | * @return 221 | */ 222 | public int queryForInt(String sql, Object[] args, int[] argTypes) throws DataAccessException 223 | { 224 | int backVal = 0; 225 | try 226 | { 227 | Integer temBack = this.jdbcTemplate.queryForObject(sql, args, argTypes, Integer.class); 228 | if (null != temBack) 229 | { 230 | backVal = temBack; 231 | } 232 | } 233 | catch (DataAccessException dataAccessException) 234 | { 235 | throw dataAccessException; 236 | } 237 | return backVal; 238 | } 239 | 240 | /** 241 | * 查询Sql,返回List 242 | */ 243 | public List queryForList(String sql) throws DataAccessException 244 | { 245 | List> backVal = null; 246 | try 247 | { 248 | backVal = this.jdbcTemplate.query(sql, new RowMapperResultSetExtractor>(new ColumnMapRowMapper(), 0)); 249 | } 250 | catch (DataAccessException dataAccessException) 251 | { 252 | throw dataAccessException; 253 | } 254 | return backVal; 255 | } 256 | 257 | /** 258 | * 查询List 259 | * 260 | * @param sql 预编译带?的sql 261 | * @param args 参数数组 262 | * @return List 263 | */ 264 | public List queryForList(String sql, Object[] args) throws DataAccessException 265 | { 266 | List> backVal = null; 267 | try 268 | { 269 | backVal = this.jdbcTemplate.query(sql, args, new RowMapperResultSetExtractor>(new ColumnMapRowMapper(), 0)); 270 | } 271 | catch (DataAccessException dataAccessException) 272 | { 273 | throw dataAccessException; 274 | } 275 | return backVal; 276 | } 277 | 278 | /** 279 | * 查询List 280 | * 281 | * @param sql 预编译带?的sql 282 | * @param args 参数数组 283 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 284 | * @return 285 | */ 286 | public List queryForList(String sql, Object[] args, int[] argTypes) throws DataAccessException 287 | { 288 | List> backVal = null; 289 | try 290 | { 291 | backVal = this.jdbcTemplate.query(sql, args, argTypes, new RowMapperResultSetExtractor>(new ColumnMapRowMapper(), 0)); 292 | } 293 | catch (DataAccessException dataAccessException) 294 | { 295 | throw dataAccessException; 296 | } 297 | return backVal; 298 | } 299 | 300 | /** 301 | * 查询Sql,返回long 302 | */ 303 | public long queryForLong(String sql) throws DataAccessException 304 | { 305 | long backVal = 0L; 306 | try 307 | { 308 | Long temBack = this.jdbcTemplate.queryForObject(sql, Long.class); 309 | if (null != temBack) 310 | { 311 | backVal = temBack; 312 | } 313 | } 314 | catch (DataAccessException dataAccessException) 315 | { 316 | throw dataAccessException; 317 | } 318 | 319 | return backVal; 320 | } 321 | 322 | /** 323 | * 查询long 324 | * 325 | * @param sql 预编译带?的sql 326 | * @param args 参数数组 327 | * @return long 328 | */ 329 | public long queryForLong(String sql, Object[] args) throws DataAccessException 330 | { 331 | long backVal = 0L; 332 | try 333 | { 334 | Long temBack = this.jdbcTemplate.queryForObject(sql, args, Long.class); 335 | if (null != temBack) 336 | { 337 | backVal = temBack; 338 | } 339 | } 340 | catch (DataAccessException dataAccessException) 341 | { 342 | throw dataAccessException; 343 | } 344 | return backVal; 345 | } 346 | 347 | /** 348 | * 查询long 349 | * 350 | * @param sql 预编译带?的sql 351 | * @param args 参数数组 352 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 353 | * @return 354 | */ 355 | public long queryForLong(String sql, Object[] args, int[] argTypes) throws DataAccessException 356 | { 357 | long backVal = 0L; 358 | try 359 | { 360 | Long temBack = this.jdbcTemplate.queryForObject(sql, args, argTypes, Long.class); 361 | if (null != temBack) 362 | { 363 | backVal = temBack; 364 | } 365 | } 366 | catch (DataAccessException dataAccessException) 367 | { 368 | throw dataAccessException; 369 | } 370 | return backVal; 371 | } 372 | 373 | /** 374 | * @param sql 375 | * @return Map 如果sql可以查到值,返回Map,否则返回null 376 | */ 377 | public Map queryForMap(String sql) throws DataAccessException 378 | { 379 | Map map = null; 380 | try 381 | { 382 | map = this.jdbcTemplate.queryForMap(sql); 383 | } 384 | catch (EmptyResultDataAccessException emptyException) 385 | { 386 | map = null; 387 | } 388 | return map; 389 | } 390 | 391 | /** 392 | * 查询Map 393 | * 394 | * @param sql 预编译带?的sql 395 | * @param args 参数数组 396 | * @return Map 397 | */ 398 | public Map queryForMap(String sql, Object[] args) throws DataAccessException 399 | { 400 | Map backVal = null; 401 | try 402 | { 403 | backVal = this.jdbcTemplate.queryForMap(sql, args); 404 | } 405 | catch (EmptyResultDataAccessException e) 406 | { 407 | e.printStackTrace(); 408 | backVal = null; 409 | } 410 | return backVal; 411 | } 412 | 413 | /** 414 | * 查询Map 415 | * 416 | * @param sql 预编译带?的sql 417 | * @param args 参数数组 418 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 419 | * @return Map 420 | */ 421 | public Map queryForMap(String sql, Object[] args, int[] argTypes) throws DataAccessException 422 | { 423 | Map backVal = null; 424 | try 425 | { 426 | backVal = this.jdbcTemplate.queryForMap(sql, args, argTypes); 427 | } 428 | catch (EmptyResultDataAccessException e) 429 | { 430 | e.printStackTrace(); 431 | backVal = null; 432 | } 433 | return backVal; 434 | } 435 | 436 | /** 437 | * 执行sql,查询String 438 | */ 439 | public String queryForString(String sql) throws DataAccessException 440 | { 441 | String backVal = null; 442 | try 443 | { 444 | backVal = (String) this.jdbcTemplate.queryForObject(sql, String.class); 445 | } 446 | catch (EmptyResultDataAccessException e) 447 | { 448 | e.printStackTrace(); 449 | backVal = null; 450 | } 451 | return backVal; 452 | } 453 | 454 | /** 455 | * 查询String 456 | * 457 | * @param sql 预编译带?的sql 458 | * @param args 参数数组 459 | * @return String 460 | */ 461 | public String queryForString(String sql, Object[] args) throws DataAccessException 462 | { 463 | String backVal = null; 464 | try 465 | { 466 | backVal = (String) this.jdbcTemplate.queryForObject(sql, args, String.class); 467 | } 468 | catch (EmptyResultDataAccessException e) 469 | { 470 | e.printStackTrace(); 471 | backVal = null; 472 | } 473 | return backVal; 474 | } 475 | 476 | /** 477 | * 查询String 478 | * 479 | * @param sql 预编译带?的sql 480 | * @param args 参数数组 481 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 482 | * @return String 483 | */ 484 | public String queryForString(String sql, Object[] args, int[] argTypes) throws DataAccessException 485 | { 486 | String backVal = null; 487 | try 488 | { 489 | backVal = (String) this.jdbcTemplate.queryForObject(sql, args, argTypes, String.class); 490 | } 491 | catch (EmptyResultDataAccessException e) 492 | { 493 | e.printStackTrace(); 494 | backVal = null; 495 | } 496 | return backVal; 497 | } 498 | 499 | /** 500 | * 查询Sql,返回List 501 | */ 502 | public List queryForBaseList(String sql) throws DataAccessException 503 | { 504 | List backVal = null; 505 | backVal = this.jdbcTemplate.query(sql, new RowMapper() 506 | { 507 | @Override 508 | public T mapRow(ResultSet rs, int i) throws SQLException 509 | { 510 | String val = rs.getString(1); 511 | return (T) val; 512 | } 513 | }); 514 | return backVal; 515 | } 516 | 517 | /** 518 | * 查询List 519 | * 520 | * @param sql 预编译带?的sql 521 | * @param args 参数数组 522 | * @return List 523 | */ 524 | public List queryForBaseList(String sql, Object[] args) 525 | { 526 | List backVal = null; 527 | backVal = this.jdbcTemplate.query(sql, args, new RowMapper() 528 | { 529 | @Override 530 | public T mapRow(ResultSet rs, int i) throws SQLException 531 | { 532 | String val = rs.getString(1); 533 | return (T) val; 534 | } 535 | }); 536 | return backVal; 537 | } 538 | 539 | /** 540 | * 查询List 541 | * 542 | * @param sql 预编译带?的sql 543 | * @param args 参数数组 544 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 545 | * @return 546 | */ 547 | public List queryForBaseList(String sql, Object[] args, int[] argTypes) 548 | { 549 | List backVal = null; 550 | backVal = this.jdbcTemplate.query(sql, args, argTypes, new RowMapper() 551 | { 552 | @Override 553 | public T mapRow(ResultSet rs, int i) throws SQLException 554 | { 555 | String val = rs.getString(1); 556 | return (T) val; 557 | } 558 | }); 559 | return backVal; 560 | } 561 | 562 | /** 563 | * 执行数据修改操作,返回影响的行数 564 | */ 565 | public int update(final String sql) throws DataAccessException 566 | { 567 | int backVal; 568 | try 569 | { 570 | backVal = this.jdbcTemplate.update(sql); 571 | } 572 | catch (DataAccessException dataAccessException) 573 | { 574 | throw dataAccessException; 575 | } 576 | return backVal; 577 | } 578 | 579 | /** 580 | * 执行数据库修改操作 581 | * 582 | * @param sql 预编译带?的sql 583 | * @param args 参数数组 584 | * @return 影响的数据行数 585 | * @throws DataAccessException 586 | */ 587 | public int update(String sql, Object[] args) throws DataAccessException 588 | { 589 | int backVal; 590 | try 591 | { 592 | backVal = this.jdbcTemplate.update(sql, args); 593 | } 594 | catch (DataAccessException dataAccessException) 595 | { 596 | throw dataAccessException; 597 | } 598 | return backVal; 599 | } 600 | 601 | /** 602 | * 执行数据库修改操作 603 | * 604 | * @param sql 预编译带?的sql 605 | * @param args 参数数组 606 | * @param argTypes 参数类型数组(使用java.sql.Types常数) 607 | * @return 影响的数据行数 608 | * @throws DataAccessException 609 | */ 610 | public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException 611 | { 612 | int backVal; 613 | try 614 | { 615 | backVal = this.jdbcTemplate.update(sql, args, argTypes); 616 | } 617 | catch (DataAccessException dataAccessException) 618 | { 619 | throw dataAccessException; 620 | } 621 | return backVal; 622 | } 623 | 624 | /** 625 | * 查询 entity List 626 | * 627 | * @param sql 预编译带?的sql 628 | * @param args 参数数组 629 | * @return List 630 | */ 631 | public List queryForModelList(String sql, Object[] args, Class cls) throws DataAccessException 632 | { 633 | List backVal = null; 634 | try 635 | { 636 | backVal = this.jdbcTemplate.query(sql, args, new BeanPropertyRowMapper(cls)); 637 | } 638 | catch (DataAccessException dataAccessException) 639 | { 640 | throw dataAccessException; 641 | } 642 | return backVal; 643 | } 644 | 645 | 646 | /** 647 | * 查询 entity 648 | * 649 | * @param sql 预编译带?的sql 650 | * @param args 参数数组 651 | * @return entity 652 | */ 653 | public T queryForModel(String sql, Object[] args, Class cls) throws DataAccessException 654 | { 655 | T backVal = null; 656 | try 657 | { 658 | backVal = this.jdbcTemplate.queryForObject(sql, args, new BeanPropertyRowMapper(cls)); 659 | } 660 | catch (EmptyResultDataAccessException dataAccessException) 661 | { 662 | backVal = null; 663 | } 664 | catch (DataAccessException dataAccessException) 665 | { 666 | throw dataAccessException; 667 | } 668 | return backVal; 669 | } 670 | 671 | } 672 | --------------------------------------------------------------------------------