1.模板设计模式
1.超类型
Action.java 行为能力接口
package com.sunxiansheng.designPattern.template;
public interface Action {
void validate();
void execute();
void after();
}
2.具体模板
ApiTemplate.java 聚合行为能力,不同的行为能力,使得模板有不同的表现
package com.sunxiansheng.designPattern.template;
import com.sunxiansheng.response.Result;
public class ApiTemplate {
public void execute(Result result, final Action action) {
try {
action.validate();
action.execute();
action.after();
result.setSuccess(true);
result.setCode(200);
} catch (Exception e) {
result.setSuccess(false);
result.setCode(500);
}
}
}
3.客户端
1.ApiDemo.java
package com.sunxiansheng.designPattern.template;
import com.sunxiansheng.response.Result;
public class ApiDemo {
public static void main(String[] args) {
ApiTemplate apiTemplate = new ApiTemplate();
Result result = Result.ok();
apiTemplate.execute(result, new Action() {
@Override
public void validate() {
System.out.println("开始校验");
}
@Override
public void execute() {
System.out.println("执行");
}
@Override
public void after() {
System.out.println("后续执行");
}
});
}
}
2.工厂+策略设计模式
1.PayChannelEnum.java 策略标识枚举
package com.sunxiansheng.designPattern.factoryandstragy;
import lombok.Getter;
@Getter
public enum PayChannelEnum {
ZFB_PAY(0, "支付宝支付"),
WX_PAY(1, "微信支付"),
BANK_PAY(2, "银行支付");
private int code;
private String desc;
PayChannelEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public static PayChannelEnum getByCode(int code) {
for (PayChannelEnum payChannelEnum : PayChannelEnum.values()) {
if (payChannelEnum.code == code) {
return payChannelEnum;
}
}
return null;
}
}
2.超类型
PayHandler.java 策略能力接口
package com.sunxiansheng.designPattern.factoryandstragy;
public interface PayHandler {
PayChannelEnum getChannel();
void dealPay();
}
3.具体实现
1.BankPayHandler.java 银行支付策略
package com.sunxiansheng.designPattern.factoryandstragy.handler;
import com.sunxiansheng.designPattern.factoryandstragy.PayChannelEnum;
import com.sunxiansheng.designPattern.factoryandstragy.PayHandler;
import org.springframework.stereotype.Component;
@Component
public class BankPayHandler implements PayHandler {
@Override
public PayChannelEnum getChannel() {
return PayChannelEnum.BANK_PAY;
}
@Override
public void dealPay() {
System.out.println("银行支付策略");
}
}
2.WxPayHandler.java 微信支付策略
package com.sunxiansheng.designPattern.factoryandstragy.handler;
import com.sunxiansheng.designPattern.factoryandstragy.PayChannelEnum;
import com.sunxiansheng.designPattern.factoryandstragy.PayHandler;
import org.springframework.stereotype.Component;
@Component
public class WxPayHandler implements PayHandler {
@Override
public PayChannelEnum getChannel() {
return PayChannelEnum.WX_PAY;
}
@Override
public void dealPay() {
System.out.println("微信支付策略");
}
}
3.ZfbPayHandler.java 支付宝支付策略
package com.sunxiansheng.designPattern.factoryandstragy.handler;
import com.sunxiansheng.designPattern.factoryandstragy.PayChannelEnum;
import com.sunxiansheng.designPattern.factoryandstragy.PayHandler;
import org.springframework.stereotype.Component;
@Component
public class ZfbPayHandler implements PayHandler {
@Override
public PayChannelEnum getChannel() {
return PayChannelEnum.ZFB_PAY;
}
@Override
public void dealPay() {
System.out.println("支付宝支付策略");
}
}
4.支付策略工厂
PayFactory.java
package com.sunxiansheng.designPattern.factoryandstragy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class PayFactory implements InitializingBean {
@Resource
private List<PayHandler> payHandlerList;
private Map<PayChannelEnum, PayHandler> handlerMap = new HashMap<>();
public PayHandler getHandlerByCode(int code) {
PayChannelEnum byCode = PayChannelEnum.getByCode(code);
return handlerMap.get(byCode);
}
@Override
public void afterPropertiesSet() throws Exception {
for (PayHandler payHandler : payHandlerList) {
handlerMap.put(payHandler.getChannel(), payHandler);
}
}
}
5.客户端
1.ServiceHandler.java 业务层,根据code可以直接执行对应策略
package com.sunxiansheng.designPattern.factoryandstragy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class ServiceHandler {
@Resource
private PayFactory payFactory;
public void dealPay(int code) {
PayHandler handlerByCode = payFactory.getHandlerByCode(code);
handlerByCode.dealPay();
}
}
2.TestController.java 测试的controller
package com.sunxiansheng.designPattern.factoryandstragy;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.Objects;
@Controller
public class PayTestController {
@Resource
private ServiceHandler serviceHandler;
@RequestMapping("/payTest/{payType}")
public void test(@PathVariable("payType") String payType) {
if (Objects.equals(payType, "支付宝")) {
serviceHandler.dealPay(PayChannelEnum.ZFB_PAY.getCode());
} else if (Objects.equals(payType, "微信")) {
serviceHandler.dealPay(PayChannelEnum.WX_PAY.getCode());
} else if (Objects.equals(payType, "银行")) {
serviceHandler.dealPay(PayChannelEnum.BANK_PAY.getCode());
}
}
}
集成websocket
1.环境搭建
1.创建新模块 sun-common-websocket
1.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sunxiansheng</groupId>
<artifactId>sun-common</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>sun-common-websocket</artifactId>
<version>${children.version}</version>
</project>
2.sun-common统一管理子模块
3.删除sun-frame对websocket模块的管理
2.配置依赖
1.sun-dependencies
<spring.websocket.version>2.4.2</spring.websocket.version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>${spring.websocket.version}</version>
</dependency>
2.sun-common-websocket
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
2.基础应用
1.目录结构
2.WebSocketConfig.java(固定配置)
package com.sunxiansheng.websocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3.WebSocketServerConfig.java
package com.sunxiansheng.websocket.config;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import java.util.List;
import java.util.Map;
@Component
public class WebSocketServerConfig extends ServerEndpointConfig.Configurator {
@Override
public boolean checkOrigin(String originHeaderValue) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
return true;
}
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
Map<String, List<String>> parameterMap = request.getParameterMap();
List<String> erpList = parameterMap.get("erp");
if (!CollectionUtils.isEmpty(erpList)) {
sec.getUserProperties().put("erp", erpList.get(0));
}
}
}
3.sun-demo使用websocket
1.引入依赖
<dependency>
<groupId>com.sunxiansheng</groupId>
<artifactId>sun-common-websocket</artifactId>
<version>${sun-common-version}</version>
</dependency>
2.SysWebSocket.java
package com.sunxiansheng.user.websocket;
import com.sunxiansheng.websocket.config.WebSocketServerConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@ServerEndpoint(value = "/sys/socket", configurator = WebSocketServerConfig.class)
@Component
public class SysWebSocket {
private static AtomicInteger onlineCount = new AtomicInteger(0);
private static Map<String, SysWebSocket> clients = new ConcurrentHashMap<>();
private Session session;
private String erp = "";
@OnOpen
public void onOpen(Session session, EndpointConfig conf) throws IOException {
try {
Map<String, Object> userProperties = conf.getUserProperties();
String erp = (String) userProperties.get("erp");
this.erp = erp;
this.session = session;
if (clients.containsKey(this.erp)) {
clients.get(this.erp).session.close();
clients.remove(this.erp);
onlineCount.decrementAndGet();
}
clients.put(this.erp, this);
onlineCount.incrementAndGet();
log.info("有新连接加入:{},当前在线人数为:{}", erp, onlineCount.get());
sendMessage("连接成功", this.session);
} catch (Exception e) {
log.error("建立链接错误{}", e.getMessage(), e);
}
}
@OnClose
public void onClose() {
try {
if (clients.containsKey(erp)) {
clients.get(erp).session.close();
clients.remove(erp);
onlineCount.decrementAndGet();
}
log.info("有一连接关闭:{},当前在线人数为:{}", this.erp, onlineCount.get());
} catch (Exception e) {
log.error("连接关闭错误,错误原因{}", e.getMessage(), e);
}
}
@OnMessage
public void onMessage(String message, Session session) {
log.info("服务端收到客户端[{}]的消息:{}", this.erp, message);
if (message.equals("ping")) {
this.sendMessage("pong", session);
}
}
@OnError
public void onError(Session session, Throwable error) {
log.error("Socket:{},发生错误,错误原因{}", erp, error.getMessage(), error);
try {
session.close();
} catch (Exception e) {
log.error("onError.Exception{}", e.getMessage(), e);
}
}
public void sendMessage(String message, Session session) {
log.info("服务端给客户端[{}]发送消息:{}", this.erp, message);
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
log.error("{}发送消息发生异常,异常原因{}", this.erp, message);
}
}
public void sendMessage(String message) {
for (Map.Entry<String, SysWebSocket> sessionEntry : clients.entrySet()) {
String erp = sessionEntry.getKey();
SysWebSocket socket = sessionEntry.getValue();
Session session = socket.session;
log.info("服务端给客户端[{}]发送消息{}", erp, message);
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
log.error("{}发送消息发生异常,异常原因{}", this.erp, message);
}
}
}
}