通过aop解决接口幂等性

master
fst1996 2023-10-04 23:32:04 +08:00
parent ef2fc75854
commit c860df28b3
12 changed files with 386 additions and 0 deletions

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml 100644
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,14 @@
package com.bwie.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Idempotent {
}

View File

@ -0,0 +1,40 @@
package com.bwie.aspect;
import com.bwie.annotation.Idempotent;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
*/
public class IdempotentAspect {
@Around("@annotation(idempotent)")
public Object independent(ProceedingJoinPoint joinPoint, Idempotent idempotent) {
Object result=null;
Map<String,Object> map=new ConcurrentHashMap<String,Object>();
String id = generateId(joinPoint.getArgs());
try {
if (map.containsKey(id)){
System.out.println("不要重复提交请求");
return map.get(id);
}
result= joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
map.put(id,result);
return result;
}
private String generateId(Object[] args){
StringBuilder stringBuilder = new StringBuilder();
for (Object arg : args) {
stringBuilder.append(arg.hashCode());
}
return stringBuilder.toString();
}
}

View File

@ -0,0 +1,9 @@
package com.bwie.common;
import lombok.Data;
@Data
public class LoginRequest {
private String userName;
private String userPwd;
}

View File

@ -0,0 +1,75 @@
package com.bwie.common;
import lombok.Data;
import java.io.Serializable;
/**
* @author DongZl
* @description:
*/
@Data
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
public static final int SUCCESS = 200;
/**
*
*/
public static final int FAIL = 500;
/**
*
*/
private int code;
/**
*
*/
private String msg;
/**
*
*/
private T data;
public static <T> Result<T> success() {
return restResult(null, SUCCESS, "操作成功");
}
public static <T> Result<T> success(T data) {
return restResult(data, SUCCESS, "操作成功");
}
public static <T> Result<T> success(T data, String msg) {
return restResult(data, SUCCESS, msg);
}
public static <T> Result<T> error() {
return restResult(null, FAIL, "操作失败");
}
public static <T> Result<T> error(String msg) {
return restResult(null, FAIL, msg);
}
public static <T> Result<T> error(T data) {
return restResult(data, FAIL, "操作失败");
}
public static <T> Result<T> error(T data, String msg) {
return restResult(data, FAIL, msg);
}
public static <T> Result<T> error(int code, String msg) {
return restResult(null, code, msg);
}
private static <T> Result<T> restResult(T data, int code, String msg) {
Result<T> apiResult = new Result<T>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
}

View File

@ -0,0 +1,25 @@
package com.bwie.controller;
import com.bwie.common.LoginRequest;
import com.bwie.common.Result;
import com.bwie.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserServiceImpl userService;
/**
*
* @param loginRequest
* @return
*/
@PostMapping("login")
public Result login(@RequestBody LoginRequest loginRequest){
return userService.login(loginRequest);
}
}

View File

@ -0,0 +1,11 @@
package com.bwie.mapper;
import com.bwie.common.LoginRequest;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
@Mapper
@Component
public interface UserMapper {
LoginRequest login(LoginRequest loginRequest);
}

View File

@ -0,0 +1,8 @@
package com.bwie.service;
import com.bwie.common.LoginRequest;
import com.bwie.common.Result;
public interface UserService {
Result login(LoginRequest loginRequest);
}

View File

@ -0,0 +1,29 @@
package com.bwie.service.impl;
import com.bwie.annotation.Idempotent;
import com.bwie.common.LoginRequest;
import com.bwie.common.Result;
import com.bwie.mapper.UserMapper;
import com.bwie.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* |
* @param loginRequest
* @return
*/
@Idempotent
public Result login(LoginRequest loginRequest) {
LoginRequest loginRequest1 = userMapper.login(loginRequest);
if (loginRequest1==null){
return Result.error("账号密码错误");
}
return Result.success();
}
}

View File

@ -0,0 +1,35 @@
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/chat?useUnicode=true&characterEncoding=utf8
username: root
password: root
name: defaultDataSource
mybatis:
mapper-locations: mappers/*xml
mybatis:
configuration:
map-underscore-to-camel-case: true
xfxh:
# 服务引擎使用 讯飞星火认知大模型V2.0,如果使用 V1.5 需要将 hostUrl 修改为 https://spark-api.xf-yun.com/v1.1/chat
hostUrl: https://spark-api.xf-yun.com/v2.1/chat
# 发送请求时指定的访问领域,如果是 V1.5版本 设置为 general如果是 V2版本 设置为 generalv2
domain: generalv2
# 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高。取值 [0,1]
temperature: 0.5
# 模型回答的tokens的最大长度V1.5取值为[1,4096]V2.0取值为[1,8192]。
maxTokens: 2048
# 大模型回复问题的最大响应时长,单位 s
maxResponseTime: 30
# 允许同时连接大模型的 websocket 数,如果是普通(免费)用户为 2超过这个数连接响应会报错具体参考官网。
QPS: 2
# 用于权限验证,从服务接口认证信息中获取
appId: 4c5ea24c
# 用于权限验证,从服务接口认证信息中获取
apiKey: d53d6f5aae8cfee01420eeff6584057f
# 用于权限验证,从服务接口认证信息中获取
apiSecret: Mzg3YTYxZjYyYTE0MTdiOTMyZTdlMTFi

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bwie.mapper.UserMapper">
<select id="login" resultType="com.bwie.common.LoginRequest">
select *from t_user where user_name=#{userName} and user_pwd=#{userPwd}
</select>
</mapper>