首頁  >  文章  >  Java Spring Boot 控制器中 RequestHeader 的重複

Java Spring Boot 控制器中 RequestHeader 的重複

WBOY
WBOY轉載
2024-02-06 11:36:10569瀏覽
問題內容

我有一組用 java 寫的 rest 控制器。最初的要求是為某些端點添加一些標頭,但是我們決定在幾乎所有 rest 控制器中添加這些標頭欄位。現在專案包含 100 多個類似的 api:

@getmapping("/products/{comp}")
public responseentity<list<product>> getallproducts(
        @requestheader(user_hdr) string user,
        @requestheader(guid_hdr) string guid,
        @requestheader(value = caller_hdr, required = false) string caller,
        @requestheader(value = lang_hdr, required = false) string language,
        @pathvariable @notnull integer comp
) {

    return responseentity.ok(service.get(comp, productutils.processheaders(user,guid,caller,language)));

}

@getmapping("/products")
public responseentity<list<product>> getallproducts(
        @requestheader(user_hdr) string user,
        @requestheader(guid_hdr) string guid,
        @requestheader(value = caller_hdr, required = false) string caller,
        @requestheader(value = lang_hdr, required = false) string language
) {

   return responseentity.ok(service.getallrecords(productutils.processheaders(user,guid,caller,language)));

}

從程式碼中可以明顯看出,元組使用者、guid、呼叫者、語言在原始碼中無所不在,但是,如何重構並將程式碼放在「一個地方」或嘗試使其更豐富,這不是很明顯嗎?可維護。例如,如果我們需要新增第 5 個參數,則需要使用 100 個 api。

在 java spring boot 中執行此操作的規範方法是什麼?

理想情況下,我想要這樣的東西:

@GetMapping("/products/{comp}")
    public ResponseEntity<List<Product>> getAllProducts(
            "common handling"
            @PathVariable @NotNull Integer comp
    ) {

        return ResponseEntity.ok(service.get(comp, ProductUtils.processHeaders(user,guid,caller,language)));

    }

    @GetMapping("/products")
    public ResponseEntity<List<Product>> getAllProducts(
            "common handling"
    ) {

       return ResponseEntity.ok(service.getAllRecords(ProductUtils.processHeaders(user,guid,caller,language)));

    }

有什麼想法嗎?控制器建議?還有別的嗎?


正確答案


為了解決程式碼重複問題並使程式碼在spring boot 應用程式中更易於維護,您可以建立一個自訂過濾器來在公共標頭到達控制器之前提取和處理它們。另外,您也可以將頭參數封裝成對象,以增強程式碼的可讀性和可維護性。

總之,透過建立requestheaders dto、實作customheaderfilter 並將其註冊到filterregistrationbean 來集中標頭處理,以在spring boot 控制器中統一應用通用標頭。

以下是建議的方法:

  1. 建立標頭 dto(資料傳輸物件):

    定義一個表示公共標頭參數的類別。此類將保存從標頭中提取的值。

    public class requestheaders {
        private string user;
        private string guid;
        private string caller;
        private string language;
    
        // getters and setters
    }
    
  2. 建立篩選器:

    實作過濾器來攔截傳入請求並提取公共標頭,然後將它們儲存在請求屬性中。

    import org.springframework.web.filter.onceperrequestfilter;
    import javax.servlet.filterchain;
    import javax.servlet.servletexception;
    import javax.servlet.http.httpservletrequest;
    import javax.servlet.http.httpservletresponse;
    import java.io.ioexception;
    
    public class customheaderfilter extends onceperrequestfilter {
        @override
        protected void dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain filterchain)
                throws servletexception, ioexception {
    
            requestheaders headers = new requestheaders();
            headers.setuser(request.getheader("user"));
            headers.setguid(request.getheader("guid"));
            headers.setcaller(request.getheader("caller"));
            headers.setlanguage(request.getheader("language"));
    
            request.setattribute("requestheaders", headers);
    
            filterchain.dofilter(request, response);
        }
    }
    
  3. 使用 filterregistrationbean 註冊過濾器:

    在主應用程式類別中使用 filterregistrationbean 註冊自訂篩選器。

    import org.springframework.boot.web.servlet.filterregistrationbean;
    import org.springframework.context.annotation.bean;
    import org.springframework.context.annotation.configuration;
    
    @configuration
    public class webconfig {
        @bean
        public filterregistrationbean<customheaderfilter> customheaderfilter() {
            filterregistrationbean<customheaderfilter> registrationbean = new filterregistrationbean<>();
            registrationbean.setfilter(new customheaderfilter());
            registrationbean.addurlpatterns("/api/*"); // adjust the url pattern as needed
            return registrationbean;
        }
    }
    

    自訂 addurlpatterns 方法以符合您希望套用篩選器的 url。

  4. 修改控制器以使用 dto:

    修改您的控制器以使用 requestheaders dto 而不是單獨的標頭參數。

    @GetMapping("/products/{comp}")
    public ResponseEntity<List<Product>> getAllProducts(@PathVariable @NotNull Integer comp,
                                                        @ModelAttribute("requestHeaders") RequestHeaders headers) {
        return ResponseEntity.ok(service.get(comp, headers));
    }
    
    @GetMapping("/products")
    public ResponseEntity<List<Product>> getAllProducts(@ModelAttribute("requestHeaders") RequestHeaders headers) {
        return ResponseEntity.ok(service.getAllRecords(headers));
    }
    

現在,如果您需要新增新的標頭參數或進行更改,您只需更新 requestheaders 類別和篩選器邏輯。這種方法集中了標頭處理並增強了可維護性。

以上是Java Spring Boot 控制器中 RequestHeader 的重複的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除