1.背景说明:近期要做一个支付网关系统,原来的网关系统买的别人的,用的技术比较老webservice,由于现在springboot比较火,关键是很好用,开箱即用,所以决定在原来系统的基础上进行改造。
2.开始动手:
原来的代码结构,如下图:
3.第一步,结构调整,先添加一个新的springboot模块:
从官网http://projects.spring.io/spring-boot/快速生成一个springboot示例,然后在主pom中添加一个新的module,命名为mag-spring-boot,我用的是idea,然后导入添加的模块。
新的项目代码结构图,去除了多余的模块,把相应的依赖进行整理:
4.代码配置以此替换,springmvc的配置替换。
web.xml的配置:
mag-facade-web
logbackConfigLocation
file:///opt/pay/config/basis/mag-tzt/mag-logback.xml
webAppRootKey
com.netfinworks.mag
dispatcher
org.springframework.web.servlet.DispatcherServlet
0
healthCheckDispatcher
com.netfinworks.common.monitor.web.servlet.HeathCheckDispatcherServlet
1
dispatcher
*.do
healthCheckDispatcher
/_health_check
contextConfigLocation
classpath:spring/applicationContext.xml
org.springframework.web.context.ContextLoaderListener
ch.qos.logback.ext.spring.web.LogbackConfigListener
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
dispatch-servlet的配置:
file:///opt/pay/config/basis/mag-tzt/mag-app.properties
file:///opt/pay/config/basis/mag-tzt/mag-sftp-config.properties
CP101
${netfinworksmq.java.naming.factory.initial}
${netfinworksmq.java.naming.provider.url}
${netfinworksmq.java.naming.security.principal}
${netfinworksmq.java.naming.security.credentials}
applicationContext.xml的配置:
首先在mag-spring-boot模块中加入spring-boot-starter-web依赖,具体该依赖都包含哪些自动配置,请参考一下链接:https://zhuanlan.zhihu.com/p/28580443?group_id=881552221710458881,支持springmvc和web开发等。具体的springboot的启动流程详解请参考链接:http://www.cnblogs.com/xinzhao/p/5551828.html,在目录resources下面新建目录MATE-INFO,再新建文件spring.factories,配置需要加载的类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.netfinworks.mag.config.WebConfig
类WebConfig继承了WebmvcConfigurerAdapter来加载springmvc配置:
package com.netfinworks.mag.config;
import ch.qos.logback.access.servlet.TeeFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import java.util.ArrayList;
import java.util.List;
/**
* WEB配置类
*
* @author zhangyongji
*/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* 对应web.xml
* -> dispatcher
* -> CharacterEncodingFilter
*
* @return
*/
@Bean
public FilterRegistrationBean encodingFilter() {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter("UTF-8", true);
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(encodingFilter);
List list = new ArrayList<>();
list.add("/");
filterRegistrationBean.setUrlPatterns(list);
return filterRegistrationBean;
}
/**
* 对应applicationContext.xml里面的配置
*
* @return
*/
@Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/static");
resolver.setSuffix(".html");
resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);
return resolver;
}
/**
* 注册试图解析器
*
* @param registry
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(getViewResolver());
}
/**
* Remote ip filter remote ip filter.
*
* @return the remote ip filter
*/
@Bean
public RemoteIpFilter remoteIpFilter() {
return new RemoteIpFilter();
}
/**
* Tee filter tee filter.
*
* @return the tee filter
*/
@Bean
@ConditionalOnProperty(prefix = "server.tomcat.accesslog", name = "debug", havingValue = "true")
public TeeFilter teeFilter() {
//复制请求响应流,用于打印调试日志
return new TeeFilter();
}
/**
* Object mapper object mapper.
*
* @return the object mapper
*/
@Bean
public ObjectMapper objectMapper() {
return new JsonMapper();
}
/**
* Http message converter http message converter.
*
* @return the http message converter
*/
@Bean
public HttpMessageConverter httpMessageConverter() {
return new MappingJackson2HttpMessageConverter(this.objectMapper());
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false) // 系统对外暴露的 URL 不会识别和匹配 .* 后缀
.setUseTrailingSlashMatch(true); // 系统不区分 URL 的最后一个字符是否是斜杠 /
}
@Override
public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
// 等价于 , 对静态资源文件的访问, 将无法 mapping 到 Controller 的 path 交给 default servlet handler 处理
configurer.enable();
}
/**
* Validator local validator factory bean.
*
* @return the local validator factory bean
*/
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setProviderClass(org.hibernate.validator.HibernateValidator.class);
return localValidatorFactoryBean;
}
/**
* Gets method validation post processor.
*
* @return the method validation post processor
*/
@Bean
public MethodValidationPostProcessor getMethodValidationPostProcessor() {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setValidator(validator());
return processor;
}
/**
* Container customizer embedded servlet container customizer.
*
* @return the embedded servlet container customizer
*/
@Bean
@ConditionalOnProperty(prefix = "server.tomcat.accesslog", name = "debug", havingValue = "true")
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new ContainerAccessLogCustomizer("logback-access.xml");
}
/**
* 这个地方要重新注入一下资源文件,不然不会注入资源的,也没有注入requestHandlerMappping,相当于xml配置的
*
*
*
* 不知道为什么,这也是spring boot的一个缺点(菜鸟觉得的)
*
* //* @param registry
*/
//@Override
//public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("swagger-ui.html")
// .addResourceLocations("classpath:/META-INF/resources/");
// registry.addResourceHandler("/webjars*")
// .addResourceLocations("classpath:/META-INF/resources/webjars/");
//}
@Bean(name = "/gateway/dptRoute.do")
public GatewayRoute getGatewayRoute() {
return new GatewayRoute();
}
}
默认错误页面,如果在下图目录下有500页面,则会加载自定义的错误页面;主要启动类,自动配置,启动定时任务,引入dubbo配置:
入口类GatewayRoute,用SpringContextUtil获取带注解@serviceRoute的类,eg:@ServiceRoute(name = "DPT_HSB_API_ALEVE_FILE"):即通过前台传过来的service名称路由到不同的类进行处理。
package com.netfinworks.mag.config;
import com.meidusa.fastjson.JSON;
import com.netfinworks.common.lang.StringUtil;
import com.netfinworks.mag.constant.RequestConstant;
import com.netfinworks.mag.domain.base.PubBaseRequestDto;
import com.netfinworks.mag.domain.base.PubBaseResponseDto;
import com.netfinworks.mag.enums.ServiceKind;
import com.netfinworks.mag.exception.CommonDefinedException;
import com.netfinworks.mag.exception.ErrorCodeException;
import com.netfinworks.mag.exception.ErrorCodeException.CommonException;
import com.netfinworks.mag.helper.RequestHelper;
import com.netfinworks.mag.service.base.IMagService;
import com.netfinworks.mag.service.base.SpringContextUtil;
import com.netfinworks.mag.service.job.Jobs;
import com.netfinworks.mag.util.tools.AuniXSS;
import com.netfinworks.mag.util.tools.MagCore;
import com.netfinworks.mag.web.verify.VerifyService;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class GatewayRoute extends AbstractController {
private static final Logger logger = LoggerFactory
.getLogger(GatewayRoute.class);
private final Charset BASIC_REQUEST_ENCODING = Charset.forName("UTF-8");
@Autowired
private VerifyService verifyService;
@Autowired
private Jobs jobs;
@Autowired
private SpringContextUtil contextUtil;
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
PubBaseResponseDto pubBaseResponseDto = new PubBaseResponseDto();
PubBaseRequestDto pubBaseRequestDto = new PubBaseRequestDto();
try {
logger.info(">>..行业统一网关接入");
Map, ?> parameters = request.getParameterMap();
if (logger.isInfoEnabled()) {
logger.info(request.getMethod()
+ ", GatewayRoute original request:"
+ JSON.toJSONString(parameters));
}
logger.info(">>..公共请求参数 request{}", parameters);
if (parameters == null || parameters.isEmpty() == true) {
// 什么参数都没有
throw CommonDefinedException.REQUIRED_FIELD_NOT_EXIST;
}
Charset charset = getEncoding(request);
logger.info(">>..charset={}", charset);
Map formattedParameters = new HashMap(
parameters.size());
for (Map.Entry, ?> entry : parameters.entrySet()) {
if (entry.getValue() == null
|| Array.getLength(entry.getValue()) == 0) {
formattedParameters.put((String) entry.getKey(), null);
} else {
if (HttpMethod.GET.name().equals(request.getMethod())) {
formattedParameters.put(
(String) entry.getKey(),
new String(((String) Array.get(
entry.getValue(), 0))
.getBytes(BASIC_REQUEST_ENCODING),
charset));
} else {
formattedParameters
.put((String) entry.getKey(), URLDecoder
.decode((String) Array.get(
entry.getValue(), 0),
charset.name()));
}
}
}
if (logger.isInfoEnabled()) {
logger.info("GatewayRoute original request format:"
+ JSON.toJSONString(formattedParameters));
}
String serviceName = getServiceName(formattedParameters);
logger.info(">>..接口名称 serviceName={}", serviceName);
IMagService service = (IMagService) contextUtil
.getServiceByAnnoName(serviceName);
// 转换为基础对象
pubBaseRequestDto = RequestHelper.convertBase(formattedParameters);
logger.info(">>..转换为基础对象 PubBaseRequestDto={}", pubBaseRequestDto);
// 验签
verify(pubBaseRequestDto, charset, formattedParameters);
// 防XSS攻击,去掉“<”和“>”
formattedParameters = auniXSS(formattedParameters);
// 获取Ip
String ip = getIpFromReq(request);
formattedParameters.put(RequestConstant.IP, ip);
// 分接口处理
pubBaseResponseDto = service.process(formattedParameters);
// 电子账户密码是否已设置可以通过接口查询账户是否已设置密码5004查询。如果已设置密码,可以直接引导客户进入提现页面
if (service.equals("DPT_HSB_API_PIN_SETUP") || service.equals("DPT_HSB_API_WITHHOLDING")) {
Map modelMap = new HashMap();
////modelMap.put("CardNbr",formattedParameters.get("CardNbr"));
////modelMap.put("MerId",formattedParameters.get("MerId"));
////modelMap.put("InputCharset",formattedParameters.get("InputCharset"));
////modelMap.put("TradeDate",formattedParameters.get("TradeDate"));
////modelMap.put("TradeTime",formattedParameters.get("TradeTime"));
////modelMap.put("CoinstCode",formattedParameters.get("CoinstCode"));
////modelMap.put("CoinstChannel",formattedParameters.get("CoinstChannel"));
////modelMap.put("ESBSource",formattedParameters.get("ESBSource"));
////modelMap.put("Sign","");
////modelMap.put("SignType","RSA");
////modelMap.put("TradeMemo","");
////modelMap.put("RetCode",RequestConstant.SYSTEM_SUCCESS);
////modelMap.put("RetMsg","交易成功");
////String respMsg = this.sign(pubBaseResponseDto);
////modelMap = (Map) JSON.parse(respMsg);
////modelMap.put("InputCharset", "UTF-8");
////String resetPwdSurl = formattedParameters.get("ResetPwdSurl");
////String resetPwdFurl = formattedParameters.get("ResetPwdFurl");
//if (pubBaseResponseDto.getAcceptStatus().equalsIgnoreCase(RequestConstant.AcceptStatus.SUCCESS)) {
// modelMap.put("AcceptStatus", RequestConstant.AcceptStatus.SUCCESS);
// return new ModelAndView(new RedirectView(resetPwdSurl), modelMap);
//} else {
// modelMap.put("AcceptStatus", RequestConstant.AcceptStatus.FAIL);
// modelMap.put("Status", RequestConstant.AcceptStatus.FAIL);
// return new ModelAndView(new RedirectView(resetPwdFurl), modelMap);
//}
//交易描述字段存放的返回的from表单数据
if (null != pubBaseResponseDto && null != pubBaseResponseDto.getTradeMemo() && pubBaseResponseDto.getTradeMemo().trim().startsWith("
service类,需要加上@ServiceRoute(name = "DPT_HSB_API_ALEVE_FILE")@Configuration注解:
package com.netfinworks.mag.service;
import com.alibaba.fastjson.JSON;
import com.chanpay.ppd.dpt.api.mch.dto.QueryMchAuthRequest;
import com.chanpay.ppd.dpt.api.mch.dto.QueryMchAuthResponse;
import com.chanpay.ppd.dpt.api.mch.facade.IMchAuthFacade;
import com.netfinworks.mag.annotation.ServiceRoute;
import com.netfinworks.mag.constant.RequestConstant;
import com.netfinworks.mag.domain.AlEveFileRequest;
import com.netfinworks.mag.domain.base.PubBaseResponseDto;
import com.netfinworks.mag.exception.CommonDefinedException;
import com.netfinworks.mag.exception.ErrorCodeException.CommonException;
import com.netfinworks.mag.helper.RequestHelper;
import com.netfinworks.mag.helper.WebServiceHelper;
import com.netfinworks.mag.service.base.MagServiceBase;
import com.netfinworks.mag.util.SftpService;
import com.netfinworks.mag.util.StreamUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.io.InputStream;
import java.util.Map;
/**
* Created by jiji on 2017/7/15.
*/
@ServiceRoute(name = "DPT_HSB_API_ALEVE_FILE")
@Configuration
public class AlEveFileService extends MagServiceBase {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private SftpService sftpService;
@Autowired
private IMchAuthFacade mchAuthFacade;
@Autowired
private WebServiceHelper webServiceHelper;
public PubBaseResponseDto process(Map paraMap) throws Exception {
getLogger().info("==== 全流水文件接口 ====");
PubBaseResponseDto response = this.handle(paraMap);
return response;
}
private PubBaseResponseDto handle(Map paraMap) throws Exception {
String cardProdNo = null;
PubBaseResponseDto response = new PubBaseResponseDto();
AlEveFileRequest request = (AlEveFileRequest) RequestHelper.convertFromMap(paraMap);
/**参数校验 -- 校验一些必输信息 以及字段长度限制*/
validaPara(request);
QueryMchAuthRequest queryMchAuthRequest = new QueryMchAuthRequest();
queryMchAuthRequest.setMerId(request.getMerId());
webServiceHelper.requestWrapper(queryMchAuthRequest);
QueryMchAuthResponse queryMchAuthResponse = mchAuthFacade.queryMchAuth(queryMchAuthRequest);
if (null != queryMchAuthResponse && null != queryMchAuthResponse.getMchAuthList() && queryMchAuthResponse.getMchAuthList().size() > 0) {
if (StringUtils.isNotEmpty(queryMchAuthResponse.getMchAuthList().get(0).getCardProdNo())) {
cardProdNo = queryMchAuthResponse.getMchAuthList().get(0).getCardProdNo();
} else {
CommonException exp = CommonDefinedException.CARD_PRODNO_EXP;
exp.setMemo("商户配置异常,请配置产品编码");
throw exp;
}
} else {
CommonException exp = CommonDefinedException.CARD_PRODNO_EXP;
exp.setMemo("商户配置异常,请配置产品编码");
throw exp;
}
Map map = new HashedMap();
logger.info("交易明细流水文件接口请求参数:" + JSON.toJSONString(request));
String files = sftpService.getFiles(request.getMerId(), request.getEveDate());
String fileName = RequestConstant.HS_BANK_CODE + "-" + "ALEVE" + cardProdNo + "-" + request.getEveDate();
if (StringUtils.isNotEmpty(files)) {
InputStream inputStream = StreamUtils.StringTOInputStream(files);
byte[] bi = StreamUtils.inputStream2Byte(inputStream);
response.setTradeMemo(fileName);
map.put("files", bi);
response.setExpandAttribute(map);
} else {
CommonException exp = CommonDefinedException.FILE_IS_NOT_EXISTS;
exp.setMemo("文件不存在");
throw exp;
}
return response;
}
}
定时任务类:
package com.netfinworks.mag.service.job;
import com.alibaba.fastjson.JSONObject;
import com.chanpay.ppd.dpt.api.mch.dto.MchAuth;
import com.chanpay.ppd.dpt.api.mch.dto.QueryMchAuthRequest;
import com.chanpay.ppd.dpt.api.mch.dto.QueryMchAuthResponse;
import com.chanpay.ppd.dpt.api.mch.facade.IMchAuthFacade;
import com.chanpay.ppd.dpt.api.security.dto.QueryMerPublicKeyRequest;
import com.chanpay.ppd.dpt.api.security.dto.QueryMerPublicKeyResponse;
import com.chanpay.ppd.dpt.api.security.dto.QueryPayPrivateKeyRequest;
import com.chanpay.ppd.dpt.api.security.dto.QueryPayPrivateKeyResponse;
import com.chanpay.ppd.dpt.api.security.facade.ISecurityFacade;
import com.netfinworks.mag.constant.RequestConstant;
import com.netfinworks.mag.exception.CommonDefinedException;
import com.netfinworks.mag.exception.ErrorCodeException.CommonException;
import com.netfinworks.mag.helper.WebServiceHelper;
import com.netfinworks.mag.util.tools.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
@Configuration
@ConfigurationProperties(prefix = "job.task")
public class Jobs {
private static Logger logger = LoggerFactory.getLogger(Jobs.class);
public static final String CACHE_NAME = "merInfo";
public final static long TOW_Hours = 2 * 60 * 60 * 1000;
//public final static long TOW_Hours = 60 * 1000;
@Autowired
private ISecurityFacade securityFacade;
@Autowired
private WebServiceHelper webServiceHelper;
@Autowired
private IMchAuthFacade mchAuthFacade;
/**
* fixedRate就是每多少分钟一次,不论你业务执行花费了多少时间,我都是1分钟执行1次
*/
@Scheduled(fixedRate = TOW_Hours)
@CacheEvict(value = CACHE_NAME, allEntries = true)
public void fixedRateJob() {
System.out.println(">>fixedRate执行,清空缓存...." + DateUtils.getDateStr());
}
@Cacheable(value = CACHE_NAME)
public QueryMerPublicKeyResponse queryMerPublicKey(String merId) throws Exception {
QueryMchAuthRequest queryMchAuthRequest = new QueryMchAuthRequest();
queryMchAuthRequest.setMerId(merId);
webServiceHelper.requestWrapper(queryMchAuthRequest);
QueryMchAuthResponse queryMchAuthResponse = mchAuthFacade.queryMchAuth(queryMchAuthRequest);
if (null != queryMchAuthResponse && null != queryMchAuthResponse.getMchAuthList() && queryMchAuthResponse.getMchAuthList().size() > 0) {
for (MchAuth mchAuth : queryMchAuthResponse.getMchAuthList()) {
if (mchAuth.getIsOpen().equals(RequestConstant.MchAuthStatus.N)) {
throw CommonDefinedException.ILLEGAL_ACCESS_SWITCH_SYSTEM;
}
}
} else {
//请求的服务,不在商户配置中
throw CommonDefinedException.ILLEGAL_ACCESS_SWITCH_SYSTEM;
}
QueryMerPublicKeyRequest queryMerPublicKeyRequest = new QueryMerPublicKeyRequest();
webServiceHelper.requestWrapper(queryMerPublicKeyRequest);
queryMerPublicKeyRequest.setMerId(merId);
logger.info("调用查询商户公钥配置请求对象:" + JSONObject.toJSONString(queryMerPublicKeyRequest));
QueryMerPublicKeyResponse queryMerPublicKeyResponse = securityFacade.queryMerPublicKey(queryMerPublicKeyRequest);
logger.info("调用查询商户公钥配置响应对象:" + (null != queryMerPublicKeyResponse ? JSONObject.toJSONString(queryMerPublicKeyResponse) : queryMerPublicKeyResponse));
// 商户服务
if (null != queryMerPublicKeyResponse && queryMerPublicKeyResponse.getRespCode().equals(RequestConstant.DPTFacade.SUCCESS)) {
return queryMerPublicKeyResponse;
} else {
CommonException exp = CommonDefinedException.QUERY_MER_KEY_EXP;
exp.setMemo("查询商户公钥失败");
throw exp;
}
}
@Cacheable(value = CACHE_NAME)
public QueryPayPrivateKeyResponse queryMerPrivateKey() throws Exception {
QueryPayPrivateKeyRequest queryPayPrivateKeyRequest = new QueryPayPrivateKeyRequest();
webServiceHelper.requestWrapper(queryPayPrivateKeyRequest);
logger.info("调用查询商户私钥配置请求对象:" + JSONObject.toJSONString(queryPayPrivateKeyRequest));
QueryPayPrivateKeyResponse queryPayPrivateKeyResponse = securityFacade.queryPayPrivateKey(queryPayPrivateKeyRequest);
logger.info("调用查询商户私钥配置响应对象:" + (null != queryPayPrivateKeyResponse ? JSONObject.toJSONString(queryPayPrivateKeyResponse) : queryPayPrivateKeyResponse));
// 商户服务
if (null != queryPayPrivateKeyResponse && queryPayPrivateKeyResponse.getRespCode().equals(RequestConstant.DPTFacade.SUCCESS)) {
return queryPayPrivateKeyResponse;
} else {
CommonException exp = CommonDefinedException.QUERY_MER_KEY_EXP;
exp.setMemo("查询商户私钥失败");
throw exp;
}
}
}
相关的主要类差不多就介绍完了,然后就可以启动调试了。
相关其他配置文件的动态打包部署可以参考链接:https://github.com/jiji87432/springboot-dubbox
启动相关脚本:https://github.com/jiji87432/nginx_sh