亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java開發(fā)如何把數(shù)據(jù)庫里的未付款訂單改成已付款

 更新時間:2022年11月14日 14:50:35   作者:肥肥技術(shù)宅  
這篇文章主要介紹了Java開發(fā)如何把數(shù)據(jù)庫里的未付款訂單改成已付款,先介紹MD5算法,簡單的來說,MD5能把任意大小、長度的數(shù)據(jù)轉(zhuǎn)換成固定長度的一串字符,實現(xiàn)思路非常簡單需要的朋友可以參考下

導言

不知道大家在網(wǎng)上購物的時候,有沒有這樣的念頭,如果能把未付款的訂單偷偷用一條SQL改成已付款,該多么美好啊。那么在實際開發(fā)過程中,我們應當如何保證數(shù)據(jù)庫里的數(shù)據(jù)在保存后不會被偷偷更改?

理論

在介紹具體的內(nèi)容之間,先介紹MD5算法,簡單的來說,MD5能把任意大小、長度的數(shù)據(jù)轉(zhuǎn)換成固定長度的一串字符,經(jīng)常玩大型游戲的朋友應該都注意到過,各種補丁包、端游客戶端之類的大型文件一般都附有一個MD5值,用于確保你下載文件的完整性。那么在這里,我們可以借鑒其思想,對訂單的某些屬性進行加密計算,得出來一個 MD5值一并保存在數(shù)據(jù)庫當中。從數(shù)據(jù)庫取出數(shù)據(jù)后第一時間進行校驗,如果有異常更改,那么及時拋出異常進行人工處理。

實現(xiàn)

道理我都懂,但是我要如何做呢,別急,且聽我一一道來。

這種需求聽起來并不強綁定于某個具體的業(yè)務(wù)需求,這就要用到了我們熟悉的鼎鼎有名的AOP(面向切面編程)來實現(xiàn)。

首先定義四個類型的注解作為AOP的切入點。@Sign@Validate都是作用在方法層面的,分別用于對方法的入?yún)⑦M行加簽和驗證方法的返回值的簽名。@SignField用于注解關(guān)鍵的不容篡改的字段。@ValidateField用于注解保存計算后得出的簽名值。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Sign {
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SignField {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidField {
}

以訂單的實體為例 sn,amt,status,userId就是關(guān)鍵字段,絕不能允許有人在落單到數(shù)據(jù)庫后對這些字段偷偷篡改。

public class Order {
    @SignField
    private String sn;
    @SignField
    private String amt;
    @SignField
    private int status;
    @SignField
    private int userId;
    @ValidField
    private String sign;
}

下面就到了重頭戲的部分,如何通過AOP來進行實現(xiàn)。

1. 定義切入點

@Pointcut("execution(@com.example.demo.annotations.Sign * *(..))")
public void signPointCut() {
 
}
 
@Pointcut("execution(@com.example.demo.annotations.Validate * *(..))")
public void validatePointCut() {
 
}

2.環(huán)繞切入點

@Around("signPointCut()")
public Object signAround(ProceedingJoinPoint pjp) throws Throwable {
    Object[] args = pjp.getArgs();
    for (Object o : args) {
        System.out.println(o);
        sign(o);
    }
    Object res = pjp.proceed(args);
    return res;
}
 
@Around("validatePointCut()")
public Object validateAround(ProceedingJoinPoint pjp) throws Throwable {
    Object[] args = pjp.getArgs();
    Object res = pjp.proceed(args);
    valid(res);
    return res;
}

3. 簽名的實現(xiàn)

1.獲取需要簽名字段

private Map<String, String> getSignMap(Object o) throws IllegalAccessException {
    Map<String, String> fieldNameToValue = new HashMap<>();
    for (Field f : o.getClass().getDeclaredFields()) {
        System.out.println(f.getName());
        for (Annotation annotation : f.getDeclaredAnnotations()) {
            if (annotation.annotationType().equals(SignField.class)) {
                String value = "";
                f.setAccessible(true);
                fieldNameToValue.put(f.getName(), f.get(o).toString());
            }
        }
    }
    return fieldNameToValue;
}

2.計算出簽名值,這里在屬性名和屬性值以外加入了我的昵稱以防止他人猜測,同時使用了自定義的分隔符來加強密碼強度。

private String getSign(Map<String, String> fieldNameToValue) {
    List<String> names = new ArrayList<>(fieldNameToValue.keySet());
    StringBuilder sb = new StringBuilder();
    for (String name : names)
        sb.append(name).append("@").append(fieldNameToValue.get(name));
    System.out.println(sb.append("日暮與星辰之間").toString());
    String signValue = DigestUtils.md5DigestAsHex(sb.toString().getBytes(StandardCharsets.UTF_8));
    return signValue;
}

找到保存簽名的字段

private Field getValidateFiled(Object o) {
    for (Field f : o.getClass().getDeclaredFields()) {
        for (Annotation annotation : f.getDeclaredAnnotations()) {
            if (annotation.annotationType().equals(ValidField.class)) {
                return f;
            }
        }
    }
    return null;
}

對保存簽名的字段進行賦值

public void sign(Object o) throws IllegalAccessException {
    Map<String, String> fieldNameToValue = getSignMap(o);
    if (fieldNameToValue.isEmpty()) {
        return;
    }
    Field validateField = getValidateFiled(o);
    if (validateField == null)
        return;
    String signValue = getSign(fieldNameToValue);
    validateField.setAccessible(true);
    validateField.set(o, signValue);
}

對從數(shù)據(jù)庫中取出的對象進行驗證

public void valid(Object o) throws IllegalAccessException {
    Map<String, String> fieldNameToValue = getSignMap(o);
    if (fieldNameToValue.isEmpty()) {
        return;
    }
    Field validateField = getValidateFiled(o);
    validateField.setAccessible(true);
    String signValue = getSign(fieldNameToValue);
    if (!Objects.equals(signValue, validateField.get(o))) {
        throw new RuntimeException("數(shù)據(jù)非法");
    }
 
}

使用示例

對將要保存到數(shù)據(jù)庫的對象進行簽名

@Sign
public Order save( Order order){
    orderList.add(order);
    return order;
}

驗證從數(shù)據(jù)庫中取出的對象是否合理

@Validate
public Order query(@ String sn){
   return orderList.stream().filter(e -> e.getSn().equals(sn)).findFirst().orElse(null);
}

到此這篇關(guān)于把數(shù)據(jù)庫里的未付款訂單改成已付款,會發(fā)生什么的文章就介紹到這了,更多相關(guān)數(shù)據(jù)庫未付款訂單改成已付款內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實現(xiàn)飯店點菜系統(tǒng)

    java實現(xiàn)飯店點菜系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)飯店點菜系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • springboot打包實現(xiàn)項目JAR包和依賴JAR包分離

    springboot打包實現(xiàn)項目JAR包和依賴JAR包分離

    這篇文章主要介紹了springboot打包實現(xiàn)項目JAR包和依賴JAR包分離,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 詳解在Java程序中運用Redis緩存對象的方法

    詳解在Java程序中運用Redis緩存對象的方法

    這篇文章主要介紹了在Java程序中運用Redis緩存對象的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • Java?IO及BufferedReader.readline()出現(xiàn)的Bug

    Java?IO及BufferedReader.readline()出現(xiàn)的Bug

    這篇文章主要介紹了Java?IO及BufferedReader.readline()出現(xiàn)的Bug,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java中Optional類及orElse方法詳解

    Java中Optional類及orElse方法詳解

    這篇文章主要為大家介紹了Java中Optional類及orElse()方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Java簡單模擬實現(xiàn)一個線程池

    Java簡單模擬實現(xiàn)一個線程池

    本文主要介紹了Java簡單模擬實現(xiàn)一個線程池,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • Spring Cloud 系列之注冊中心 Eureka詳解

    Spring Cloud 系列之注冊中心 Eureka詳解

    Netflix Eureka 是由 Netflix 開源的一款基于 REST 的服務(wù)發(fā)現(xiàn)組件,包括 Eureka Server 及 Eureka Client。這篇文章主要介紹了Spring Cloud 系列之注冊中心 Eureka,需要的朋友可以參考下
    2020-11-11
  • java解析excel文件的方法

    java解析excel文件的方法

    這篇文章主要介紹了java解析excel文件的方法,這里整理相關(guān)的代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • Java如何輸出windows中的全部漢字

    Java如何輸出windows中的全部漢字

    這篇文章主要介紹了Java如何輸出windows中的全部漢字問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 在Java中如何對類進行排序詳解

    在Java中如何對類進行排序詳解

    這篇文章主要給大家介紹了關(guān)于如何在Java中使用Arrays.toString()對類進行排序的相關(guān)資料,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-08-08

最新評論