在使用 Spring Data JPA 中的 @CreatedDate
註解時,如果希望自動填充建立時間欄位,通常需要結合 @EntityListeners(AuditingEntityListener.class)
註解一起使用。這是因為 @CreatedDate
等審計註解通常與審計事件監聽器(AuditingEntityListener)一起工作,用於處理實體的審計資訊。
審計欄位-自動填充
當您定義一個實體類(例如 EntityBase
)並希望使用 @CreatedDate
註解來自動設定建立時間時,可以按照以下步驟操作:
- 在實體類中新增
@CreatedDate
註解,實體可抽象成一個類,如EntityBase,AuditBase等:
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class EntityBase {
/**
* 建立人
*/
@Column(name = "created_by")
@CreatedBy
private String createdBy;
/**
* 修改人
*/
@Column(name = "updated_by")
@LastModifiedBy
private String updatedBy;
/**
* 建立時間
*/
@Column(name = "created_time")
@CreatedDate
private java.time.LocalDateTime createdTime;
/**
* 更新時間
*/
@Column(name = "update_time")
@LastModifiedDate
private java.time.LocalDateTime updateTime;
}
-
確保審計事件監聽器生效:
確保AuditingEntityListener
能夠正確監聽實體類的審計事件,並在儲存實體物件時自動填充相應的審計資訊,包括建立時間等。 -
實現AuditorAware介面,返回當前登入的使用者,以便填充create_by欄位,同時開啟審計功能@EnableJpaAuditing:
@EnableJpaAuditing
@Component
public class AuditorAwareImpl implements AuditorAware {
@Override
public Optional getCurrentAuditor() {
return Optional.of("lind");
}
}
透過以上步驟,您可以在訂閱 EntityBase
實體類時使用 @CreatedDate
註解,並結合 @EntityListeners(AuditingEntityListener.class)
註解來自動填充建立時間欄位,從而實現審計功能。
AuditorAware獲取請求頭資訊
要在實現 AuditorAware
介面的 getCurrentAuditor()
方法中獲取當前請求頭(HTTP Header)中的變數,您可以藉助 Spring 提供的 RequestContextHolder
和 ServletRequestAttributes
來訪問當前請求的上下文資訊。具體步驟如下:
-
獲取當前請求的 HttpServletRequest 物件:
- 首先,您需要從
RequestContextHolder.getRequestAttributes()
獲取當前請求的ServletRequestAttributes
物件。 - 然後透過
ServletRequestAttributes
物件獲取當前的HttpServletRequest
物件。
- 首先,您需要從
-
從 HttpServletRequest 中獲取請求頭資訊:
- 在
HttpServletRequest
物件中,您可以使用getHeader()
方法來獲取指定名稱的請求頭資訊。
- 在
下面是一個示例程式碼,演示瞭如何在 AuditorAware
的 getCurrentAuditor()
方法中獲取當前請求頭中的變數:
import org.springframework.data.domain.AuditorAware;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
@EnableJpaAuditing
@Component
public class CustomAuditorAware implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
String customHeaderValue = request.getHeader("Custom-Header");
return Optional.ofNullable(customHeaderValue);
}
return Optional.empty();
}
}
如果是基於netty的WEB框架,需要使用下面程式碼獲取請求頭引數
@EnableJpaAuditing
@Component
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
Object request = RpcContext.getServiceContext().getRequest();
if (request != null) {
NettyRequestFacade requestFacade = (NettyRequestFacade) request;
if (requestFacade != null && requestFacade.getHeader("preferred_username") != null) {
return Optional.of(requestFacade.getHeader("preferred_username"));
}
}
return Optional.of("none");
}
}
在上述程式碼中,我們透過 RequestContextHolder
獲取當前請求的上下文資訊,並從中提取出請求頭中名為 Custom-Header
的自定義變數值。最後將該值作為審計人員資訊返回。
請注意,在使用
RequestContextHolder
時,確保上下文中包含請求資訊,否則可能會出現空指標異常。另外,這種方式適用於基於 Spring MVC 或 Spring WebFlux 的應用。