Springboot+AOP が時間パラメータ形式変換を実装する方法
前書き
シナリオ
フロントエンドから渡された時間パラメーターは、バックエンドで必要な任意のカスタム時間形式に変換できます。
さまざまなビジネス シナリオでは、フロント エンドに接続すると、コントロールの基本的な時間パラメーターは固定形式になります。フロント エンドが時間パラメーターの形式を変換しないようにするために、フロントエンドと合意し、固定フォーマットをバックエンドに渡すように依頼し、必要に応じてフォーマットを変換できます。
効果
① 次を使用して yyyy-MM-dd HH:mm:ss から yyyy-MM-dd に変換します:
② yyyyMMddHHmmss から yyyy-MM-dd HH:mm:ss に変換するには、次を使用します。
③ これ以上の例はありませんが、実際には、好きなように変換できます。
実際の戦闘
pom.xml (aop 依存関係、lombok 依存関係):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>1.9.5</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.0</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
Core (カスタム アノテーション インターセプター):
カスタム アノテーション 1
DateField.java
目的: 時間形式の変換が必要なフィールドをマークし、古い形式、新しい形式を構成するために使用されます (デフォルト値を書き込むことができます)。
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Author: JCccc * @Date: 2022-4-11 18:45 * @Description: */ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface DateField { String oldPattern() default DateUtil.YYYY_MM_DD_HH_MM_SS; //新格式可以写默认也可以不写,如果业务比较固定,那么新时间格式和旧时间格式都可以固定写好 String newPattern() default ""; }
カスタム アノテーション 2
NeedDateFormatConvert.java
目的: AOP 時間形式の変換が必要なインターフェイスをマークするために使用されます。
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Author: JCccc * @Date: 2022-4-11 18:44 * @Description: */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface NeedDateFormatConvert { }
Interceptor
DateFormatAspect.java
目的: コア変換実装ロジック。
import com.jctest.dotestdemo.util.DateUtil; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import java.lang.reflect.Field; import java.util.Objects; /** * @Author: JCccc * @Date: 2022-4-11 18:57 * @Description: */ @Aspect @Component public class DateFormatAspect { private static Logger log = LoggerFactory.getLogger(DateFormatAspect.class); @Pointcut("@annotation(com.jctest.dotestdemo.aop.dateFormat.NeedDateFormatConvert)") public void pointCut() { } @Around("pointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { //转换 dateFormat(joinPoint); return joinPoint.proceed(); } public void dateFormat(ProceedingJoinPoint joinPoint) { Object[] objects = null; try { objects = joinPoint.getArgs(); if (objects.length != 0) { for (int i = 0; i < objects.length; i++) { //当前只支持判断对象类型参数 convertObject(objects[i]); } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("参数异常"); } } /** * 转换对象里面的值 * * @param obj * @throws IllegalAccessException */ private void convertObject(Object obj) throws IllegalAccessException { if (Objects.isNull(obj)) { log.info("当前需要转换的object为null"); return; } Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { boolean containFormatField = field.isAnnotationPresent(DateField.class); if (containFormatField) { //获取访问权 field.setAccessible(true); DateField annotation = field.getAnnotation(DateField.class); String oldPattern = annotation.oldPattern(); String newPattern = annotation.newPattern(); Object dateValue = field.get(obj); if (Objects.nonNull(dateValue) && StringUtils.hasLength(oldPattern) && StringUtils.hasLength(newPattern)) { String newDateValue = DateUtil.strFormatConvert(String.valueOf(dateValue), oldPattern, newPattern); if (Objects.isNull(newDateValue)){ log.info("当前需要转换的日期数据转换失败 dateValue = {}",dateValue.toString()); throw new RuntimeException("参数转换异常"); } field.set(obj, newDateValue); } } } } }
ツールクラス
DateUtil.java
目的: さまざまな時刻形式を定義する時刻形式変換関数。
import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** * @Author: JCccc * @Date: 2022-4-1 14:48 * @Description: */ @Slf4j public class DateUtil { public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; public static final String YYYY_MM_DD = "yyyy-MM-dd"; public static final String YYYY_MM = "yyyy-MM"; public static final String YYYY = "yyyy"; public static final String MM = "MM"; public static final String DD = "dd"; public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; public static final String YYYYMMDD = "yyyyMMdd"; /** * 指定日期格式转换 * * @param dateStr * @param oldPattern * @return */ public static String strFormatConvert(String dateStr, String oldPattern,String newPattern) { try { DateTimeFormatter oldFormatter = DateTimeFormatter.ofPattern(oldPattern); DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern(newPattern); return LocalDateTime.parse(dateStr, oldFormatter).format(newFormatter); } catch (Exception e) { log.error("strToDate is Exception. e:", e); return null; } } }
UserQueryVO.java
import com.jctest.dotestdemo.aop.dateFormat.DateField; import com.jctest.dotestdemo.util.DateUtil; import lombok.Data; import java.io.Serializable; /** * @Author: JCccc * @Date: 2022-4-1 14:48 * @Description: */ @Data public class UserQueryVO implements Serializable { /** * 开始时间 */ @DateField(oldPattern =DateUtil.YYYY_MM_DD_HH_MM_SS, newPattern = DateUtil.YYYY_MM_DD) private String startDate; /** * 结束时间 */ @DateField(oldPattern =DateUtil.YYYY_MM_DD_HH_MM_SS,newPattern = DateUtil.YYYY_MM_DD) private String endDate; }
Interface
import com.jctest.dotestdemo.aop.dateFormat.NeedDateFormatConvert; import com.jctest.dotestdemo.vo.UserQueryVO; import org.springframework.web.bind.annotation.*; /** * @Author: JCccc * @Date: 2022-4-18 11:52 * @Description: */ @RestController public class UserController { @NeedDateFormatConvert @PostMapping("/test") public String test( @RequestBody UserQueryVO userQueryVO){ System.out.println("时间格式转化完成:"); System.out.println(userQueryVO.getStartDate()); System.out.println(userQueryVO.getEndDate()); return userQueryVO.toString(); } }
Call
以上がSpringboot+AOP が時間パラメータ形式変換を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Jasypt の概要 Jasypt は、開発者が最小限の労力で基本的な暗号化機能を自分のプロジェクトに追加できる Java ライブラリであり、暗号化の仕組みを深く理解する必要はありません。一方向および双方向暗号化の高いセキュリティ。標準ベースの暗号化テクノロジー。パスワード、テキスト、数値、バイナリを暗号化します... Spring ベースのアプリケーション、オープン API への統合、JCE プロバイダーでの使用に適しています... 次の依存関係を追加します: com.github.ulisesbocchiojasypt-spring-boot-starter2. 1.1 Jasypt の特典はシステムのセキュリティを保護し、コードが漏洩した場合でもデータ ソースは保証されます。

使用シナリオ 1. 注文は正常に行われましたが、支払いが 30 分以内に行われませんでした。支払いがタイムアウトになり、注文が自動的にキャンセルされました 2. 注文に署名があり、署名後 7 日間評価が行われませんでした。注文がタイムアウトして評価されない場合、システムはデフォルトでプラスの評価を設定します 3. 注文は正常に行われます。販売者が 5 分間注文を受け取らない場合、注文はキャンセルされます。 4. 配送がタイムアウトします。 SMS リマインダーをプッシュします... 遅延が長く、リアルタイム パフォーマンスが低いシナリオでは、タスク スケジュールを使用して定期的なポーリング処理を実行できます。例: xxl-job 今日は選択します

1. Redis は分散ロックの原則を実装しており、分散ロックが必要な理由 分散ロックについて話す前に、分散ロックが必要な理由を説明する必要があります。分散ロックの反対はスタンドアロン ロックです。マルチスレッド プログラムを作成するとき、共有変数を同時に操作することによって引き起こされるデータの問題を回避します。通常、ロックを使用して共有変数を相互に除外し、データの正確性を確保します。共有変数の使用範囲は同じプロセス内です。共有リソースを同時に操作する必要があるプロセスが複数ある場合、どうすれば相互排他的になるのでしょうか?今日のビジネス アプリケーションは通常マイクロサービス アーキテクチャであり、これは 1 つのアプリケーションが複数のプロセスをデプロイすることも意味します。複数のプロセスが MySQL の同じレコード行を変更する必要がある場合、順序の乱れた操作によって引き起こされるダーティ データを避けるために、分散が必要です。今回導入するスタイルはロックされています。ポイントを獲得したい

Springboot はファイルを読み取りますが、jar パッケージにパッケージ化した後、最新の開発にアクセスできません。jar パッケージにパッケージ化した後、Springboot がファイルを読み取れない状況があります。その理由は、パッケージ化後、ファイルの仮想パスが変更されるためです。は無効であり、ストリーム経由でのみアクセスできます。読み取ります。ファイルはリソースの下にあります publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

SpringBoot と SpringMVC はどちらも Java 開発で一般的に使用されるフレームワークですが、それらの間には明らかな違いがいくつかあります。この記事では、これら 2 つのフレームワークの機能と使用法を調べ、その違いを比較します。まず、SpringBoot について学びましょう。 SpringBoot は、Spring フレームワークに基づいたアプリケーションの作成と展開を簡素化するために、Pivotal チームによって開発されました。スタンドアロンの実行可能ファイルを構築するための高速かつ軽量な方法を提供します。

Springboot+Mybatis-plus が SQL ステートメントを使用して複数テーブルの追加操作を実行しない場合、私が遭遇した問題は、テスト環境で思考をシミュレートすることによって分解されます: パラメーターを含む BrandDTO オブジェクトを作成し、パラメーターをバックグラウンドに渡すことをシミュレートします。 Mybatis-plus で複数テーブルの操作を実行するのは非常に難しいことを理解してください。Mybatis-plus-join などのツールを使用しない場合は、対応する Mapper.xml ファイルを設定し、臭くて長い ResultMap を設定するだけです。対応する SQL ステートメントを記述します。この方法は面倒に見えますが、柔軟性が高く、次のことが可能です。

1. RedisAPI のデフォルトのシリアル化メカニズムである RedisTemplate1.1 をカスタマイズします。API ベースの Redis キャッシュ実装では、データ キャッシュ操作に RedisTemplate テンプレートを使用します。ここで、RedisTemplate クラスを開いて、クラスのソース コード情報を表示します。publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations、BeanClassLoaderAware{//キーを宣言、値の各種シリアル化メソッド、初期値は空 @NullableprivateRedisSe

プロジェクトでは、構成情報が必要になることがよくありますが、この情報はテスト環境と本番環境で構成が異なる場合があり、実際のビジネス状況に基づいて後で変更する必要がある場合があります。これらの構成をコードにハードコーディングすることはできません。構成ファイルに記述することをお勧めします。たとえば、この情報を application.yml ファイルに書き込むことができます。では、コード内でこのアドレスを取得または使用するにはどうすればよいでしょうか?方法は2つあります。方法 1: @Value アノテーションが付けられた ${key} を介して、構成ファイル (application.yml) 内のキーに対応する値を取得できます。この方法は、マイクロサービスが比較的少ない状況に適しています。方法 2: 実際には、プロジェクト、業務が複雑な場合、ロジック
