1. 导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>myService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>myService</name>
<description>myService</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
<cxf-spring-boot-starter.version>3.5.3</cxf-spring-boot-starter.version>
<xstream.version>1.4.19</xstream.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.15</version>
</dependency>
<!--配置多数据源依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!--json格式-->
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.39</version>
</dependency>
<!-- cxf webservice 依赖 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>${cxf-spring-boot-starter.version}</version>
</dependency>
<!-- xml bean 转换工具类-->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>${xstream.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
<!--压缩依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>asm</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.15</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.1</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>org.example.myservice.MyServiceApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2. 写配置
spring:
profiles: #启动运行环境
active: dev
# 连接池配置
datasource:
druid:
initial-size: 5 #初始化连接池大小
min-idle: 5 #最小连接数
max-active: 20 #最大连接数
max-wait: 60000 #最长等待时间
#单位:ms,默认1min,两个作用
#1.Destroy线程运行周期,每隔多久运行一次,配合min-evictable-idle-time-millis和max-evictable-idle-time-millis使用;
#2.若testWhileIdle为true,申请连接时,若空闲时间大于time-between-eviction-runs-millis,则执行validation-query语句检测连接是否有效。
time-between-eviction-runs-millis: 60000 #关闭空闲连接间隔(ms)
# 单位:ms,连接保持空闲而不被驱逐的最小时间,默认30min
#连接被destroy线程关闭条件:大于minIdle且空闲时间大于1800000
min-evictable-idle-time-millis: 300000
test-while-idle: true #判断连接是否可用
test-on-borrow: true #在获得连接前是否要进行测试
test-on-return: false #在归还连接前是否要进行测试
remove-abandoned: false #用于自动回收超时连接
remove-abandoned-timeout: 1800
#pool-prepared-statements: false #不缓存pstmt,oracle可以配true
#max-pool-prepared-statement-per-connection-size: 20 #配置pstmt缓存个数
filters: stat, wall
validation-query: SELECT 'x' #数据库状态检测
aop-patterns: com.eleadmin.*.*.service.*
#配置servlet,开启druid登录页和首页
stat-view-servlet:
url-pattern: /druid/*
reset-enable: true
login-username: admin
login-password: admin
application-dev.yml
server: #开发环境
port: 8082
spring:
# 配置文件上传的大小
servlet:
multipart:
max-file-size: 200MB
jackson: #格式时间格式--在数据库添加的时候存入时间是转换后的时间
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
datasource:
dynamic:
primary: db1 # 配置默认数据库
datasource:
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/dome?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true&allowMultiQueries=true
username: root
password: 123456
redis:
host: 127.0.0.1 # Redis服务器地址
port: 6379 # Redis服务器连接端口
database: 0 # Redis数据库索引(默认为0)
jedis:
pool:
max-active: 10 # 最大的连接数
max-idle: 10 # 最大最小的空闲连接数
min-idle: 0
max-wait: -1 # 最大阻塞时间 -1 没有限制
mybatis-plus:
#配置映射器的位置
mapper-locations: classpath*:/mapper/**Mapper.xml
#打印sql日志
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#这是因为mybatis默认开启驼峰命名法,按规则数据表中的lastName字段应对应实体类中的last_name属性,
#而实体类中的lastName属性应对应数据表中的last_name字段。
map-underscore-to-camel-case: true
3. cxfConfig
package org.example.myservice.config;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.example.myservice.service.cxf.IptvUserService;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.xml.ws.Endpoint;
/**
* cxf配置
*
* @author th
* @date 2024/03/07
*/
@Configuration
public class CxfConfig {
/**
* iptvUser请求
*/
@Resource
private IptvUserService iptvUserService;
/**
* 暴露接口-http://127.0.0.1:8082/soap
*
* @return
*/
@Bean
public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(
new CXFServlet(),
"/soap/*"
);
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint iptvUserServiceEndpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), iptvUserService);
endpoint.publish("/cxf/bossUser");
return endpoint;
}
}
4. 写cxf接口
IptvUserService.java
package org.example.myservice.service.cxf;
import org.example.myservice.service.cxf.impl.vo.ExecCmdResponse;
import org.example.myservice.service.cxf.impl.vo.Product;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
* iptv用户服务
*
* @Package: org.example.myservice.service.cxf
* @ClassName: IptvUserService
* @作者: th
* @创建时间: 2024/3/7 10:12
* @描述:
* @date 2024/03/07
*/
@WebService(targetNamespace = "http://cxf.service.myservice.example.org"// 命名空间,一般是接口的包名倒序
)
public interface IptvUserService {
/**
* 增加新用户,开户后用户激活
*
* @param BossUsercode BOSS计费账号(重庆移动使用用户手机号码作为计费账号)
* @param Userid 业务子帐号
* @param Password 密码
* @param STBID 用户绑定的机顶盒ID(机顶盒32位串号)
* @param Areacode 用户所属业务区代码省市区
* @param Productlist 用户订购的产品列表(数组),用户开户订购的产品。重庆移动开户只携带一个基础产品。
* @param UsergroupID 用户分组ID,用于区分用户分组。
* @return
*/
// WebMethod注解配置的是接口的方法名
@WebMethod(operationName = "SubscriptionUser")
ExecCmdResponse SubscriptionUser(@WebParam(name = "BossUsercode") String BossUsercode,
@WebParam(name = "Userid") String Userid,
@WebParam(name = "Password") String Password,
@WebParam(name = "STBID") String STBID,
@WebParam(name = "Areacode") String Areacode,
@WebParam(name = "Productlist") Product Productlist,
@WebParam(name = "UsergroupID") int UsergroupID
);
@WebMethod(operationName = "test01")
ExecCmdResponse test01(@WebParam(name = "BossUsercode") String BossUsercode,
@WebParam(name = "Userid") String Useri
);
/**
* 取消订阅用户
*
* @param userid userid
* @param state 状态
* @return {@link ExecCmdResponse}
*/
@WebMethod(operationName = "UnsubscriptionUser")
ExecCmdResponse UnsubscriptionUser(@WebParam(name = "userid") String userid,
@WebParam(name = "state") String state
);
}
IptvUserServiceImpl.java
package org.example.myservice.service.cxf.impl;
import lombok.extern.slf4j.Slf4j;
import org.example.myservice.aspect.Logging;
import org.example.myservice.service.cxf.IptvUserService;
import org.example.myservice.service.cxf.impl.vo.ExecCmdResponse;
import org.example.myservice.service.cxf.impl.vo.Product;
import org.springframework.stereotype.Service;
import javax.jws.WebService;
/**
* iptv用户服务实现
*
* @author th
* @Package: org.example.myservice.service.cxf.impl
* @ClassName: IptvUserServiceImpl
* @作者: th
* @创建时间: 2024/3/7 10:35
* @描述:
* @date 2024/03/07
*/
@Slf4j
@Service
@WebService(serviceName = "IptvUserService",
targetNamespace = "http://cxf.service.myservice.example.org",
endpointInterface = "org.example.myservice.service.cxf.IptvUserService")
public class IptvUserServiceImpl implements IptvUserService {
@Override
@Logging(isWebService = true)
public ExecCmdResponse SubscriptionUser(String BossUsercode, String Userid, String Password, String STBID, String Areacode, Product Productlist, int UsergroupID) {
log.info("SubscriptionUser: BossUsercode:{}, Userid:{}, Password:{}, STBID:{}, Areacode:{}, Productlist:{}, UsergroupID:{}", BossUsercode, Userid, Password, STBID, Areacode, Productlist, UsergroupID);
ExecCmdResponse response = new ExecCmdResponse();
response.setResult(0);
response.setErrorDescription("succ");
return response;
}
@Override
public ExecCmdResponse test01(String BossUsercode, String Useri) {
log.warn("test01: BossUsercode:{}, Useri:{}", BossUsercode, Useri);
ExecCmdResponse response = new ExecCmdResponse();
response.setResult(0);
response.setErrorDescription("succ");
return response;
}
@Override
public ExecCmdResponse UnsubscriptionUser(String userid, String state) {
log.info("UnsubscriptionUser: userid:{}, state:{}", userid, state);
ExecCmdResponse response = new ExecCmdResponse();
response.setResult(0);
response.setErrorDescription("succ");
return response;
}
}
5. 控制层
package org.example.myservice.controller;
import org.example.myservice.client.LiveMetadataManagementClient;
import org.example.myservice.common.JsonResult;
import org.example.myservice.service.cxf.impl.vo.Product;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/**
* <p>
* PBOSS用户表 前端控制器
* </p>
*
* @author admin
* @since 2024-03-07 11:05:47
*/
@RestController
@RequestMapping("/bossUserEntity")
public class BossUserController {
@RequestMapping("/get")
public JsonResult get() {
String url = "http://127.0.0.1:8082/soap/cxf/bossUser?wsdl";
boolean b = false;
try {
b = LiveMetadataManagementClient.c1("1", url, "13912345678", "zz13912345678");
} catch (IOException e) {
throw new RuntimeException(e);
}
return JsonResult.ok().setData(b);
}
@RequestMapping("/getAdd")
public JsonResult getAdd() {
String url = "http://127.0.0.1:8082/soap/cxf/bossUser?wsdl";
boolean b = false;
try {
Product p = new Product();
p.setProductID("1234567890");
b = LiveMetadataManagementClient.UserAdd(url, "13912345678", "zz13912345678", "1234567890", "机顶盒id", "502252525", p, 1);
} catch (IOException e) {
throw new RuntimeException(e);
}
return JsonResult.ok().setData(b);
}
}
对应的vo
package org.example.myservice.service.cxf.impl.vo;
import javax.xml.bind.annotation.XmlElement;
import java.io.Serializable;
/**
* 响应
*
* @author th
* @date 2024/03/07
*/
public class ExecCmdResponse implements Serializable {
private int Result;
private String ErrorDescription = "";
@XmlElement(name = "Result")
public int getResult() {
return Result;
}
public void setResult(int result) {
Result = result;
}
@XmlElement(name = "ErrorDescription")
public String getErrorDescription() {
return ErrorDescription;
}
public void setErrorDescription(String errorDescription) {
ErrorDescription = errorDescription;
}
}
Product
@Data
public class Product implements Serializable {
/**
* OTT产品编号
*/
private String ProductID;
}
ResultNotifyVO
package org.example.myservice.service.cxf.impl.vo;
import lombok.Data;
/**
* @author kai
*/
@Data
public class ResultNotifyVO {
/**
* 接收消息结果
* 0:成功 -1:失败
*/
private int Result;
/**
* 错误信息详细描述
*/
private String ErrorDescription;
}
6. client客户端-发送请求
package org.example.myservice.client;
import lombok.extern.slf4j.Slf4j;
import org.example.myservice.service.cxf.impl.vo.Product;
import org.example.myservice.utils.WebServiceClientUtil;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
/**
* soap客户端
*
* @author wukai
* @date 2022/7/12 14:16
*/
@Slf4j
public class LiveMetadataManagementClient {
/**
* 移动id-C2
*/
public static final String ID = "CQYDCOS3";
/**
* U_ADD_XML格式-添加用户
*/
public static String U_ADD_XML;
/**
* U_XH_XML格式-销户
*/
public static String U_XH_XML;
static {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// 读取C1_REQ_XML格式
Resource resource = resolver.getResource("classpath:cxf/User-add.xml");
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()))) {
U_ADD_XML = bufferedReader.lines().collect(Collectors.joining());
} catch (IOException e) {
throw new RuntimeException(e);
}
// 读取移动C1_REQ_XML格式
resource = resolver.getResource("classpath:cxf/User-xh.xml");
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()))) {
U_XH_XML = bufferedReader.lines().collect(Collectors.joining());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 发送c1请求
*
* @param domain 下发域-判断走向接口
* @param url 接口地址
* @param BossUsercode BOSS计费账号
* @param Useri 业务子帐号
* @return boolean
* @throws IOException IOException
*/
public static boolean c1(String domain, String url, String BossUsercode, String Useri) throws IOException {
String content = String.format(
"0".equals(domain) ? U_ADD_XML : U_XH_XML,
BossUsercode, Useri);
String response = WebServiceClientUtil.httpClientPost(url, content, "");
log.info("c1反馈,domain:{},url:{},BossUsercode:{},Useri:{},response:{}", domain, url, BossUsercode, Useri, response);
return true;
}
/**
* 用户添加
*
* @param BossUsercode BOSS计费账号(重庆移动使用用户手机号码作为计费账号)
* @param Userid 业务子帐号
* @param Password 密码
* @param STBID 用户绑定的机顶盒ID(机顶盒32位串号)
* @param Areacode 用户所属业务区代码省市区
* @param Productlist 用户订购的产品列表(数组),用户开户订购的产品。重庆移动开户只携带一个基础产品。
* @param UsergroupID 用户分组ID,用于区分用户分组。
* @param url url
* @return boolean
* @throws IOException IOException
*/
public static boolean UserAdd(String url, String BossUsercode, String Userid, String Password, String STBID, String Areacode, Product Productlist, int UsergroupID) throws IOException {
String content = String.format(U_ADD_XML, BossUsercode, Userid, Password, STBID, Areacode, Productlist, UsergroupID);
String response = WebServiceClientUtil.httpClientPost(url, content, "");
log.info("c1反馈,url:{},BossUsercode:{},Userid:{},Password:{},STBID:{},Areacode:{},Productlist:{},UsergroupID:{},response:{}", url, BossUsercode, Userid, Password, STBID, Areacode, Productlist, UsergroupID, response);
return true;
}
//
// /**
// * 发送c2回执
// *
// * @param url c2回执地址
// * @param correlateId 相关性标识
// * @param cspId 互相约定的上层标识
// * @param cmdResult 命令执行结果:0:成功 -1:通常失败 其他结果待定义
// */
// public static boolean c2Notify(String url, String correlateId, String cspId, String lspId, Integer cmdResult) throws IOException {
// String content = String.format(C2_NOTIFY_XML, cspId, lspId, correlateId, cmdResult, "");
// String response = WebServiceClientUtil.httpClientPost(url, content, "");
// // TODO: 2022/7/4 可能需要根据播控返回的response判断是否处理成功
// return true;
// }
}
7. WebServiceClientUtil
package org.example.myservice.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.http.ResponseEntity;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author kai
*/
@Slf4j
public class WebServiceClientUtil {
/**
* 使用apache的HttpClient发送http请求
*
* @param url 请求的WSDL地址(或ASMX
* @param content 请求的完整XML报文
* @param soapAction 命名空间+方法名, 如为SOAP1.2协议不需要此项
* @return XML字符串
*/
public static String httpClientPost(String url, String content, String soapAction) throws IOException {
// 获得Http客户端
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// 创建Post请求
HttpPost httpPost = new HttpPost(url);
RequestConfig config = RequestConfig.custom()
// 默认连接超时5s
.setConnectionRequestTimeout(5000)
// 请求超时5s
.setSocketTimeout(5000)
.build();
httpPost.setConfig(config);
// 将数据放入entity中
StringEntity entity = new StringEntity(content, "UTF-8");
httpPost.setEntity(entity);
// 响应模型
String result;
CloseableHttpResponse response = null;
try {
// 设置请求头
// 特别说明一下,此处为SOAP1.1协议
// 如果用的是SOAP1.2协议,改为:"application/soap+xml;charset=UTF-8"
httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
// 命名空间+方法名
// 如为SOAP1.2协议不需要此项
httpPost.setHeader("SOAPAction", soapAction);
// 由客户端执行(发送)Post请求
response = httpClient.execute(httpPost);
// 从响应模型中获取响应实体
HttpEntity responseEntity = response.getEntity();
log.info("发送URL为:{}", url);
log.info("发送内容为:{}", content);
log.info("响应ContentType为:{}", responseEntity.getContentType());
log.info("响应状态为:{}", response.getStatusLine());
result = EntityUtils.toString(responseEntity);
log.info("响应内容为: {}", result);
} finally {
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
}
return result;
}
/**
* 使用Spring Boot的RestTemplate发送http请求
*
* @param url 请求的WSDL地址(或ASMX)
* @param content 请求的完整XML报文
* @param soapAction 命名空间+方法名, 如为SOAP1.2协议不需要此项
* @return XML字符串
*/
public static String restTemplatePost(String url, String content, String soapAction) {
Map<String, String> headers = new HashMap<>();
// 设置请求头
// 特别说明一下,此处为SOAP1.1协议
// 如果用的是SOAP1.2协议,改为:"application/soap+xml;charset=UTF-8"
headers.put("Content-Type", "text/xml;charset=UTF-8");
// 命名空间+方法名
// 如为SOAP1.2协议不需要此项
headers.put("SOAPAction", soapAction);
ResponseEntity<String> entity = RestTemplateUtils.post(url, headers, content, String.class);
System.out.println(entity.getStatusCode());
System.out.println(entity.getBody());
log.info("发送URL为:{}", url);
log.info("发送内容为:{}", content);
return entity.getBody();
}
}
8. cxf.xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cxf="http://cxf.service.myservice.example.org">
<soapenv:Header/>
<soapenv:Body>
<cxf:SubscriptionUser>
<!--Optional:-->
<BossUsercode>%s</BossUsercode>
<!--Optional:-->
<Userid>%s</Userid>
<!--Optional:-->
<Password>%s</Password>
<!--Optional:-->
<STBID>%s</STBID>
<!--Optional:-->
<Areacode>%s</Areacode>
<!--Optional:-->
<Productlist>
<!--Optional:-->
<productID>%s</productID>
</Productlist>
<UsergroupID>%s</UsergroupID>
</cxf:SubscriptionUser>
</soapenv:Body>
</soapenv:Envelope>
9. aop切换,注解获取日志
LoggingAspect.java
package org.example.myservice.aspect;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.jws.WebService;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
/**
* webService日志方面
*
* @author th
* @date 2024/03/11
*/
@Slf4j
@Aspect
@Component
public class LoggingAspect {
/**
* 创建环绕通知切点,切点以日志注解开启
*/
@Pointcut("@annotation(org.example.myservice.aspect.Logging)")
public void pointcut() {
}
/**
* 织入通知
*
* @return
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
// 1.获取注解信息 pjp.getTarget().getClass().getAnnotation 无法直接获取自定义的上下文注解,需要通过执行方法获取
// 执行方法需要通过方法签名得到方法的方法名,执行空间
// 获取方法签名
MethodSignature signature = (MethodSignature) pjp.getSignature();
// 得到执行方法
Method method = signature.getMethod();
Class<?> clazz = pjp.getTarget().getClass();
Method declaredMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
// 获取方法上的注解,存在日志注解才进行以下操作
Logging logging = declaredMethod.getAnnotation(Logging.class);
if (logging != null) {
long start = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
// 2.如果日志注解开启webservice信息记录
if (logging.isWebService()) {
// 获取webservice请求信息
WebService webService = clazz.getAnnotation(WebService.class);
// 请求地址
String namespace = webService.targetNamespace();
sb.append("WebService请求地址:").append(namespace).append("/").append(webService.serviceName());
} else {
// http请求获取请求信息
Object[] args = pjp.getArgs();
for (Object arg : args) {
if (arg instanceof HttpServletRequest) {
sb.append("http请求地址:")
.append(((HttpServletRequest) arg).getRequestURI());
// .append("请求头信息:").append(((HttpServletRequest) arg).getHeader());
}
}
}
Object[] args = pjp.getArgs();
sb.append("; 入参:").append(JSON.toJSONString(args));
// 3.方法处理前记录请求
log.info(sb.toString());
Object proceed = pjp.proceed();
// 4.记录方法处理后结果
log.info("耗时:{}s; 输出参数:{}, ", (System.currentTimeMillis() - start) / 1000, JSON.toJSONString(proceed));
return proceed;
}
return pjp.proceed();
}
}
注解是打在IptvUserServiceImpl 服务实现方法上的
@Override
@Logging(isWebService = true)
public ExecCmdResponse SubscriptionUser(String BossUsercode, String Userid, String Password, String STBID, String Areacode, Product Productlist, int UsergroupID) {
log.info("SubscriptionUser: BossUsercode:{}, Userid:{}, Password:{}, STBID:{}, Areacode:{}, Productlist:{}, UsergroupID:{}", BossUsercode, Userid, Password, STBID, Areacode, Productlist, UsergroupID);
ExecCmdResponse response = new ExecCmdResponse();
response.setResult(0);
response.setErrorDescription("succ");
return response;
}
这里只是记录一下,如果有更好的方式 ,方便告知一下