Jump to content

Search the Community

Showing results for tags 'java'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


About Me

Found 5 results

  1. Version 1.0.1

    30 downloads

    注意编辑config.yml里面的配置信息! 这个机器人能做什么? 输入#帮助: 输入服主设置的自定义关键词可查询服务器 功能列表 输入 #全体玩家 服务器关键词 |来获取全部玩家 输入 #换图 服务器关键词 地图名称 |来更换服务器地图 输入 #换图列表 |来查看服务器地图列表 输入 #踢出 服务器关键词 玩家名称 理由 |来踢出一名玩家 输入 #封锁 服务器关键词 steam64ID 小时(0表示永久) 理由 |来封锁一个玩家 输入 #解ban 服务器关键词 steam64ID |来解封一名玩家 输入 #VIP列表 服务器关键词 |来查看VIP列表 输入 #添加VIP 服务器关键词 玩家名称 steam64ID |来添加一个VIP 输入 #删除VIP 服务器关键词 玩家名称 steam64ID |来删除一个VIP 输入 #处罚 服务器关键词 玩家名称 理由 |来处罚一名玩家 输入 #重置投票触发阈值 服务器关键词 |来重置 输入 #广播消息 消息内容 |向服务器发送一条消息 输入 #管理员列表 服务器关键词 |查询服务器的全部管理员 输入 #添加管理员 服务器关键词 玩家名称 steam64ID 角色(owner是服主) |来添加一个管理员 输入 #删除管理员 服务器关键词 玩家名称 steam64ID 角色(owner是服主) |来删除一个管理员
  2. 当时密码加密我还是停留在盐,第一次用Spring Security的时候,接触到了 BCryptPasswordEncoder 这个加密,当时非常好奇这个算法,因为它每次加密的密码都是不一样的,动态的 拆开发现,两个关键方法 BCrypt.hashpw和BCrypt.gensalt 仔细看能发现这个加密算法是用的强哈希+盐+密钥,默认情况是的密码,因为使用到了哈希,所以是密码是不可逆的,这样就算你密码泄露了别人也不知道密码明文是什么 看gensalt 有没有很熟悉 这个盐和生成的密码前缀是不是有点像,生成了一个带盐的哈希 再看hashpw 里面一大堆代码都是在校验密文 注意看,这里已经开始截取上面生成的哈希盐了 String real_salt = salt.substring(off + 3, off + 25); 最后工序就是解码base64和编码64 然后生成的结果就是我们现在看见的,同一个密码,每一次都不一样的密文 这个是一个非常强大的好用的加密方法,反正我是比较喜欢的!因为都不需要在数据库里把盐给存起来
  3. 查询steam游戏服务器信息API,可查询arma3,dayz等steam游戏 新建类 ServerPlayer.java 封装玩家信息 package com.destiny.kaiheila.destinybot.SteamServerQuery; public class ServerPlayer { public int PlayerIndex; public String PlayerName; public long PlayerScore; public float PlayerDuration; public ServerPlayer(int Index, String Name, long Score, float Duration) { this.PlayerIndex = Index; this.PlayerName = Name; this.PlayerScore = Score; this.PlayerDuration = Duration; } public int getIndex() { return this.PlayerIndex; } public String getName() { return this.PlayerName; } public long getScore() { return this.PlayerScore; } public float getDuration() { return this.PlayerDuration; } } 新建 SteamServerChallenge.java steam查询头 package com.destiny.kaiheila.destinybot.SteamServerQuery; public class SteamServerChallenge { public static int HEADER = (byte)0x41; } 新建 SteamServerEnvironment.java 专用服务器操作系统标识 package com.destiny.kaiheila.destinybot.SteamServerQuery; public class SteamServerEnvironment { public static int LINUX = 108; public static int WINDOWS = 119; public static int MAC = 109; } 新建 SteamServerInfo.java 服务器信息 package com.destiny.kaiheila.destinybot.SteamServerQuery; import java.nio.ByteBuffer; import java.nio.ByteOrder; public class SteamServerInfo { private int position = 0; public static byte HEADER = (byte)0x49; private int ServerProtocol; private byte[] ServerName; private byte[] ServerMap; private byte[] ServerFolder; private byte[] ServerGame; private short ServerAppID; private int ServerPlayers; private int ServerMaxPlayers; private int ServerBots; private int ServerType; private int ServerEnvironment; private int ServerVisibility; private int ServerVAC; private byte[] ServerVersion; private int ServerEDF; public SteamServerInfo(byte[] Buffer) { this.ServerProtocol = Buffer[0]; this.position++; int ServerNameLength = this.getStringLenght(this.position, Buffer); this.ServerName = new byte[ServerNameLength]; System.arraycopy(Buffer, this.position, this.ServerName, 0, ServerNameLength); this.position = this.position + ServerNameLength + 1; int ServerMapLength = this.getStringLenght(this.position, Buffer); this.ServerMap = new byte[ServerMapLength]; System.arraycopy(Buffer, this.position, this.ServerMap, 0, ServerMapLength); this.position = this.position + ServerMapLength + 1; int ServerFolderLength = this.getStringLenght(this.position, Buffer); this.ServerFolder = new byte[ServerFolderLength]; System.arraycopy(Buffer, this.position, this.ServerFolder, 0, ServerFolderLength); this.position = this.position + ServerFolderLength + 1; int ServerGameLength = this.getStringLenght(this.position, Buffer); this.ServerGame = new byte[ServerGameLength]; System.arraycopy(Buffer, this.position, this.ServerGame, 0, ServerGameLength); this.position = this.position + ServerGameLength + 1; this.ServerAppID = ByteBuffer.wrap(Buffer, this.position, this.position + 1).order(ByteOrder.LITTLE_ENDIAN).getShort(); this.position = this.position + 2; this.ServerPlayers = Buffer[this.position]; this.position++; this.ServerMaxPlayers = Buffer[this.position]; this.position++; this.ServerBots = Buffer[this.position]; this.position++; this.ServerType = Buffer[this.position]; this.position++; this.ServerEnvironment = Buffer[this.position]; this.position++; this.ServerVisibility = Buffer[this.position]; this.position++; this.ServerVAC = Buffer[this.position]; this.position++; int ServerVersionLength = getStringLenght(this.position, Buffer); this.ServerVersion = new byte[ServerVersionLength]; System.arraycopy(Buffer, this.position, this.ServerVersion, 0, ServerVersionLength); this.position = this.position + ServerVersionLength + 1; this.ServerEDF = Buffer[this.position]; } public int getProtocol() { return this.ServerProtocol; } public String getName() { return new String(this.ServerName); } public String getMap() { return new String(this.ServerMap); } public String getFolder() { return new String(this.ServerFolder); } public String getGame() { return new String(this.ServerGame); } public short getAppID() { return this.ServerAppID; } public int getPlayers() { return this.ServerPlayers; } public int getMaxPlayers() { return this.ServerMaxPlayers; } public int getBots() { return this.ServerBots; } public int getType() { return this.ServerType; } public int getEnvironment() { return this.ServerEnvironment; } public int getVisibility() { return this.ServerVisibility; } public int getVAC() { return this.ServerVAC; } public String getVersion() { return new String(this.ServerVersion); } public int getEDF() { return this.ServerEDF; } private int getStringLenght(int start, byte[] buffer) { for (int i = start; i < buffer.length; i++) { if (buffer[i] == 0) { return i - start; } } return 0; } @Override public String toString() { return "Protocol : " + this.getProtocol() + "\nName : " + this.getName() + "\nMap : " + this.getMap() + "\nFolder : " + this.getFolder() + "\nGame : " + this.getGame() + "\nAppID : " + this.getAppID() + "\nPlayers : " + this.getPlayers() + "\nMax Players : " + this.getMaxPlayers() + "\nBots : " + this.getBots() + "\nServer Type : " + (char)this.getType() + " (d = DEDICATED|l = NON-DEDICATED|p = SourceTV/proxy)\nEnvironment : " + (char)this.getEnvironment() + " (l = Linux|w = Windows|m = MAC)\nVisibility : " + this.getVisibility() + " (0 = Public|1 = Private)\nVAC : " + this.getVAC() + " (0 = UNSECURED|1 = SECURED)\nVersion : " + this.getVersion() + "\nExtra Data Flag (EDF) : " + this.getEDF(); } } 新建 SteamServerPlayer.java 服务器玩家信息 package com.destiny.kaiheila.destinybot.SteamServerQuery; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class SteamServerPlayer { private int position = 0; public static byte HEADER = (byte)0x44; public int PlayersLength; public ServerPlayer[] Players; public SteamServerPlayer(byte[] Buffer) { this.PlayersLength = Buffer[this.position]; this.Players = new ServerPlayer[this.getPlayersLength()]; this.position++; for (int i = 0; i < this.getPlayersLength(); i++) { int PlayerIndex = Buffer[this.position]; this.position++; int PlayerNameLength = getStringLenght(this.position, Buffer); byte[] PlayerName = new byte[PlayerNameLength]; System.arraycopy(Buffer, this.position, PlayerName, 0, PlayerNameLength); this.position = this.position + PlayerNameLength + 1; long PlayerScore = ((Buffer[this.position + 3] & 0xFFL) << 24) | ((Buffer[this.position + 2] & 0xFFL) << 16) | ((Buffer[this.position + 1] & 0xFFL) << 8) | ((Buffer[this.position + 0] & 0xFFL) << 0); this.position = this.position + 4; float PlayerDuration = ByteBuffer.wrap(new byte[] {Buffer[this.position], Buffer[this.position+1], Buffer[this.position+2], Buffer[this.position+3]}).order(ByteOrder.LITTLE_ENDIAN).getFloat(); this.position = this.position + 4; this.Players[i] = new ServerPlayer(PlayerIndex, new String(PlayerName), PlayerScore, PlayerDuration); } } public int getPlayersLength() { return this.PlayersLength; } public ServerPlayer[] getPlayers() { return this.Players; } private int getStringLenght(int start, byte[] buffer) { for (int i = start; i < buffer.length; i++) { if (buffer[i] == 0) return i - start; } return 0; } public List<Map<String,Object>> playerList (){ List<Map<String,Object>> listMap = new ArrayList<>(); for (ServerPlayer Player : this.getPlayers()) { Map<String,Object> map = new HashMap<>(); map.put("playerName",Player.getName() ); map.put("Score", Long.parseLong(String.valueOf(Player.getScore()))); map.put("Duration",Math.round(Player.getDuration() / 3600) + ":" + Math.round((Player.getDuration() % 3600) / 60) + ":" + Math.round((Player.getDuration() % 3600) % 60)); listMap.add(map); } return listMap; } public String toString() { String PlayerTable = ""; for (ServerPlayer Player : this.getPlayers()) { PlayerTable += Player.getName() + ((Player.getName().length() <= 7) ? "\t\t\t\t" : ((Player.getName().length() <= 15) ? "\t\t\t" : ((Player.getName().length() <= 23) ? "\t\t" : "\t"))); PlayerTable += new Long(Player.getScore()).intValue() + "\t\t"; PlayerTable += Math.round(Player.getDuration() / 3600) + ":" + Math.round((Player.getDuration() % 3600) / 60) + ":" + Math.round((Player.getDuration() % 3600) % 60) + "\n"; } return "Players : " + this.getPlayersLength() + "\nPlayer Name :\t\t\tScore :\t\tDuration:\n" + PlayerTable; } } 新建SteamServerQuery.java steam主服务器查询 package com.destiny.kaiheila.destinybot.SteamServerQuery; import java.net.*; public class SteamServerQuery { private InetAddress ServerAddress; private int ServerPort; private DatagramSocket UDPClient; public SteamServerQuery(InetAddress Address, int Port) { try { this.UDPClient = new DatagramSocket(); this.ServerAddress = Address; this.ServerPort = Port; } catch (SocketException e) { e.printStackTrace(); } } public SteamServerQuery(String Address, int Port) throws UnknownHostException { this(InetAddress.getByName(Address), Port); } public SteamServerQuery(String Address) throws UnknownHostException { this(Address.split(":")[0], Integer.parseInt(Address.split(":")[1])); } public DatagramSocket getDatagramSocket() { return UDPClient; } public SteamServerInfo getInfo() throws Exception { byte[] InfoHeader = new byte[25]; InfoHeader[0] = (byte)0xFF; InfoHeader[1] = (byte)0xFF; InfoHeader[2] = (byte)0xFF; InfoHeader[3] = (byte)0xFF; InfoHeader[4] = (byte)0x54; byte[] SourceString = new String("Source Engine Query").getBytes(); System.arraycopy(SourceString, 0, InfoHeader, 5, SourceString.length); InfoHeader[5 + SourceString.length] = (byte) 0x00; DatagramPacket SendInfoPacket = new DatagramPacket(InfoHeader, InfoHeader.length, this.ServerAddress, this.ServerPort); this.UDPClient.setSoTimeout(3000); this.UDPClient.send(SendInfoPacket); byte[] ReceivedBuffer = new byte[512]; DatagramPacket ReceivedInfoPacket = new DatagramPacket(ReceivedBuffer, ReceivedBuffer.length); UDPClient.setSoTimeout(3000); this.UDPClient.receive(ReceivedInfoPacket); if (ReceivedBuffer[0] == (byte)0xFF && ReceivedBuffer[1] == (byte)0xFF && ReceivedBuffer[2] == (byte)0xFF && ReceivedBuffer[3] == (byte)0xFF && ReceivedBuffer[4] == SteamServerInfo.HEADER) { byte[] ServerInfoBuffer = new byte[ReceivedBuffer.length - 5]; System.arraycopy(ReceivedBuffer, 5, ServerInfoBuffer, 0, ServerInfoBuffer.length); return new SteamServerInfo(ServerInfoBuffer); } return null; } public SteamServerPlayer getPlayer() throws Exception{ byte[] PlayerHeader = this.getChallenge(); PlayerHeader[4] = (byte)0x55; DatagramPacket SendPlayerPacket = new DatagramPacket(PlayerHeader, PlayerHeader.length, this.ServerAddress, this.ServerPort); this.UDPClient.send(SendPlayerPacket); byte[] ReceivedPlayerBuffer = new byte[1024]; DatagramPacket ReceivedPlayerPacket = new DatagramPacket(ReceivedPlayerBuffer, ReceivedPlayerBuffer.length); this.UDPClient.setSoTimeout(3000); this.UDPClient.receive(ReceivedPlayerPacket); if (ReceivedPlayerBuffer[0] == (byte)0xFF && ReceivedPlayerBuffer[1] == (byte)0xFF && ReceivedPlayerBuffer[2] == (byte)0xFF && ReceivedPlayerBuffer[3] == (byte)0xFF && ReceivedPlayerBuffer[4] == SteamServerPlayer.HEADER) { byte[] ServerPlayerBuffer = new byte[ReceivedPlayerBuffer.length - 5]; System.arraycopy(ReceivedPlayerBuffer, 5, ServerPlayerBuffer, 0, ServerPlayerBuffer.length); return new SteamServerPlayer(ServerPlayerBuffer); } else { System.err.println("ERROR Player Packet !"); return null; } } public byte[] getChallenge() throws Exception { byte[] ChallengeHeader = new byte[9]; ChallengeHeader[0] = (byte)0xFF; ChallengeHeader[1] = (byte)0xFF; ChallengeHeader[2] = (byte)0xFF; ChallengeHeader[3] = (byte)0xFF; ChallengeHeader[4] = (byte)0x55; ChallengeHeader[5] = (byte)0xFF; ChallengeHeader[6] = (byte)0xFF; ChallengeHeader[7] = (byte)0xFF; ChallengeHeader[8] = (byte)0xFF; DatagramPacket SendChallengePacket = new DatagramPacket(ChallengeHeader, ChallengeHeader.length, this.ServerAddress, this.ServerPort); this.UDPClient.send(SendChallengePacket); byte[] ReceivedChallengeBuffer = new byte[9]; DatagramPacket ReceivedChallengePacket = new DatagramPacket(ReceivedChallengeBuffer, ReceivedChallengeBuffer.length); this.UDPClient.setSoTimeout(3000); this.UDPClient.receive(ReceivedChallengePacket); if(ReceivedChallengeBuffer[0] == (byte)0xFF && ReceivedChallengeBuffer[1] == (byte)0xFF && ReceivedChallengeBuffer[2] == (byte)0xFF && ReceivedChallengeBuffer[3] == (byte)0xFF && ReceivedChallengeBuffer[4] == SteamServerChallenge.HEADER) { return ReceivedChallengeBuffer; } else { System.err.println("ERROR Challenge Packet !"); return new byte[9]; } } } 使用方法: //参数 IP:查询端口 SteamServerQuery ServerQuery = new SteamServerQuery("0.0.0.0:2303"); //从服务器获取服务器信息 SteamServerInfo ServerInfo = ServerQuery.getInfo(); //从服务器获取玩家信息 SteamServerPlayer player = ServerQuery.getPlayer(); ServerInfo..... player.... SteamServerQuery.7z
  4. 在application.yml文件中配置web以及rabbitmq的配置信息 spring: rabbitmq: host: 127.0.0.1 port: 5672 username: root password: 9YoIu # 发送者开启 return 确认机制 publisher-returns: true # 发送者开启 confirm 确认机制 publisher-confirm-type: correlated listener.simple: # 设置消费端手动 ack acknowledge-mode: manual # 是否支持重试 retry: enabled: true 在maven中引入依赖: <!--MQ消息队列--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> 使用@EnableRabbit注解在入口类上启用MQ @SpringBootApplication @EnableRabbit public class SmsEmailApplication { public static void main(String[] args) { SpringApplication.run(SmsEmailApplication.class, args); } } 新建rabbitmq配置类 @Configuration public class RabbitmqConfig { @Bean public MessageConverter messageConverter() { return new Jackson2JsonMessageConverter(); } //配置正常业务 例如邮件发送 的队列交换机与通道 public static String Queue1 = "queue_1"; public static String Exchange1 = "exchange_1"; public static String Routing1 = "routing_key_1"; /** * 定义死信队列相关信息 */ public final static String deadQueueName = "dead_queue"; public final static String deadRoutingKey = "dead_routing_key"; public final static String deadExchangeName = "dead_exchange"; /** * 死信队列 交换机标识符 */ public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange"; /** * 死信队列交换机绑定键标识符 */ public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key"; /** * 创建死信交换机 */ @Bean public DirectExchange deadExchange() { return new DirectExchange(deadExchangeName); } /** * 创建配置死信队列 * * @return */ @Bean public Queue deadQueue() { Queue queue = new Queue(deadQueueName, true); return queue; } /** * 死信队列与死信交换机绑定 */ @Bean public Binding bindingDeadExchange() { return BindingBuilder.bind(deadQueue()).to(deadExchange()).with(deadRoutingKey); } /** * 队列绑定到死信 * 第一个参数是创建的queue的名字,第二个参数是是否支持持久化 * @return */ @Bean public Queue EmailQueue() { // 将普通队列绑定到死信队列交换机上 Map<String, Object> args = new HashMap<>(2); args.put(DEAD_LETTER_QUEUE_KEY, deadExchangeName); args.put(DEAD_LETTER_ROUTING_KEY, deadRoutingKey); Queue queue = new Queue(Queue1, true, false, false, args); return queue; } /** * 创建交换机 * 一共有三种构造方法,可以只传exchange的名字, 第二种,可以传exchange名字,是否支持持久化,是否可以自动删除, * 第三种在第二种参数上可以增加Map,Map中可以存放自定义exchange中的参数 * @return */ @Bean public DirectExchange EmailExchange() { return new DirectExchange(Exchange1, true, false); } /** * 绑定 * @param Queue * @param Exchange * @return */ @Bean public Binding bindingFinanceExchange(Queue Queue1, DirectExchange Exchange) { return BindingBuilder.bind(EmailQueue()).to(Exchange1).with(Routing); } } 新建消费者类RabbitReceiver /** 消息队列监听器 * * @param message */ @RabbitListener(queues = "queue_1") @RabbitHandler public void process(JSONObject data, Channel channel, Message message) throws IOException { //消息手动确认 channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //消息重新投递 channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true); //消息是否重复 if(message.getMessageProperties().getRedelivered()){ //拒绝消息 channel.basicReject(message.getMessageProperties().getDeliveryTag(),false); //拒绝消费消息(丢失消息) 重新投递给死信队列 channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false); } } /** * 死信 消息队列消费者 * 当无法消费且被投递至死信队列则再次被死信消费 * @param message * @param headers * @param channel * @throws Exception */ @RabbitListener(queues = "dead_queue") @RabbitHandler public void deadProcess(Message message, @Headers Map<String, Object> headers, Channel channel) throws Exception { // 获取消息Id String messageId = message.getMessageProperties().getMessageId(); String msg = new String(message.getBody(), "UTF-8"); // // 手动ack Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG); // 手动签收 channel.basicAck(deliveryTag, false); log.error("日志已记录...."); } 投递一条消息 @Resource RabbitTemplate rabbitTemplate; //生成一个随机消息ID public static Message getId (JSONObject data){ return MessageBuilder.withBody(JSON.toJSONString(data).getBytes()) .setContentType(MessageProperties.CONTENT_TYPE_JSON) .setContentEncoding("utf-8") .setMessageId(UUID.randomUUID()+"") .build(); } /** * 投递消息 * 通过自定义设置消息体给每一个消息设置一个唯一ID,方便失败时候重试 * @param sendData 要发送的数据 * @param async 如果开启此项,交换机会马上把所有的信息都交给所有的消费者,消费者再自行处理,不会因为消费者处理慢而阻塞线程。 返回一个null * 如果禁用此项,交换机会同步消费者。使用此方法,当确认了所有的消费者都接收成功之后,才接收另外一个 会造成阻塞 返回一个object * rabbitTemplate.convertAndSend 里接受3个参数 第一个是之前配置的交换机,第二个是配置好的routing_key,第三个是消息体 */ public Object sendSmsEmail(JSONObject sendData,boolean async){ //自定义消息体 必须给消息指定一个UUID,用于失败重试 Message message = getId(sendData); if (async){ rabbitTemplate.convertAndSend("exchange_1","routing_key_1",message); return null; }else{ return rabbitTemplate.convertSendAndReceive("exchange_1","routing_key_1",message); } } 现在我们在浏览器中输入:http://localhost:15672 可以看到一个登录界面 查看队列,features行下的普通交换机有一个 DLX 的标志,就说明已绑定了死信交换机
  5. 那么我们可以简化,使用自己写的一个注解注入到服务层,让其自己完成必须参数的校验功能 maven项目引入 <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> </dependency> 建一个实体类对象 public class Parameter { @NotEmpty(message="姓名不能为空") private String name; @Min(value = 18, message = "年龄必须大于18岁") private int age; @NotEmpty(message="hobbies不能为空") private List<String> hobbies; } 新建一个自定义注解接口 /**检查方法实体类是否符合规则 * @author qilong */ //在自定义注解的时候可以使用@Documented来进行标注,如果使用@Documented标注了,在生成javadoc的时候就会把@Documented注解给显示出来。 @Documented //@Retention可以用来修饰注解,是注解的注解,称为元注解。RetentionPolicy.RUNTIME运行时注解,注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在; @Retention(RetentionPolicy.RUNTIME) //注解的作用目标METHOD——方法,TYPE——接口、类、枚举、注解 @Target({ElementType.METHOD, ElementType.TYPE}) public @interface EntityCheck { /** * 是否打印输出拦截日志 * @return */ boolean debug() default false; } 新建一个类用以实现AOP /**实体类检查切面 * @author qilong */ @Aspect @Component @Slf4j public class EntityCheckAspect { //之前注解接口的路径 @Pointcut("@annotation(zx.cloud.commons.utils.entityCheck.EntityCheck)") public void pointEntityCheck() { } /** * 环绕切入点 * 匹配指定包包下所有使用@Service注解的类 * @param proceedingJoinPoint * @return * @throws Throwable */ @Around(value = "pointEntityCheck()") private Object entityCheck(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { // 获取切入的方法对象 // 这个m是代理对象的,没有包含注解 Method m = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod(); // this()返回代理对象,target()返回目标对象,目标对象反射获取的method对象才包含注解 Method methodWithAnnotations = proceedingJoinPoint.getTarget().getClass().getDeclaredMethod( proceedingJoinPoint.getSignature().getName(), m.getParameterTypes()); EntityCheck annotation = methodWithAnnotations.getAnnotation(EntityCheck.class); if (annotation.debug()) { log.info("实体类验证:拦截到包:{} 方法:{}", proceedingJoinPoint.getTarget().getClass().getName(), proceedingJoinPoint.getSignature().getName()); } //获取所有参数 Object[] args = proceedingJoinPoint.getArgs(); for (Object o: args) { if (o instanceof BindingResult){ //校验不通过如果有错误 不执行方法直接返回出去 String re = getError((BindingResult)o); if (null != re) { //NormalResponse 是我自己的返回的格式,你可以自定义,例如返回一个map,String 都可以 return new NormalResponse(Code.FAIL, re); } } } //参数校验没有错误继续执行方法 return proceedingJoinPoint.proceed(args); } //自定义错误返回, 当实体类校验不通过,这里会直接返回给前端 public static String getError(BindingResult result) { StringBuffer errorInfo = new StringBuffer(); if (result.hasErrors()) { List<FieldError> fieldErrors = result.getFieldErrors(); for (FieldError error : fieldErrors) { errorInfo.append(String.format("参数 %s错误: %s ", error.getField(), error.getDefaultMessage())); } return errorInfo.toString(); } else { return null; } } } 服务层 @Slf4j @Service public class TestServiceImpl implements TestService { //加上我们自定义的注解 @EntityCheck @Override public NormalResponse createAutoProvisioningGroup(Parameter entity, BindingResult result) { log.info("没有遇到参数错误我已被运行!"); } } 访问你的接口,如果有参数不对,就不会执行服务层,被@EntityCheck注解检查后拦截返回,至此自定义参数校验注解完成!
×
×
  • Create New...