Làm cách nào để ghi đè biểu tượng yêu thích của Spring Boot?
LƯU Ý : Đây là một câu hỏi khác của tôi cung cấp một giải pháp khác không liên quan đến bất kỳ mã hóa nào: Spring Boot: Có thể sử dụng các tệp application.properties bên ngoài trong các thư mục tùy ý với một lọ béo không? Nó dành cho application.properties, nhưng nó cũng có thể được áp dụng cho favicon. Trên thực tế, tôi đang sử dụng phương pháp đó để ghi đè biểu tượng yêu thích.
Nếu tôi triển khai một lớp có @EnableWebMvc, thì lớp WebMvcAutoConfiguration của Spring Boot không tải và tôi có thể phục vụ biểu tượng yêu thích của riêng mình bằng cách đặt nó vào thư mục gốc của nội dung tĩnh.
Nếu không, WebMvcAutoConfiguration đăng ký đậu faviconRequestHandler, (xem nguồn https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ web / WebMvcAutoConfiguration.java ) và nó phục vụ biểu tượng 'lá xanh' được đặt trong thư mục tài nguyên chính của Spring Boot.
Làm cách nào để tôi có thể ghi đè nó mà không cần triển khai một lớp có @EnableWebMvc, do đó vô hiệu hóa toàn bộ chức năng cấu hình mặc định của lớp WebMvcAutoConfiguration của Spring Boot?
Ngoài ra, vì tôi muốn tệp biểu tượng được cập nhật càng sớm càng tốt ở phía máy khách (trình duyệt web), tôi muốn đặt khoảng thời gian lưu trong bộ nhớ cache của tệp favicon thành 0 (như mã sau, tôi đang sử dụng cho nội dung ứng dụng web 'tĩnh' và các tệp tập lệnh phải được cập nhật ở phía máy khách càng sớm càng tốt sau khi tôi thay đổi tệp.)
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Vì vậy, chỉ để tìm nơi lưu tệp favicon.ico mà các danh hiệu faviconRequestHandler của Spring Boot có thể là không đủ.
CẬP NHẬT
Bây giờ tôi biết rằng tôi có thể ghi đè tệp mặc định bằng cách đặt tệp biểu tượng yêu thích vào thư mục src / main / resources. Nhưng vấn đề khoảng thời gian bộ nhớ cache vẫn còn.
Ngoài ra, bạn nên đặt tệp favicon vào thư mục chứa các tệp web tĩnh, hơn là thư mục tài nguyên.
CẬP NHẬT
Được rồi, tôi đã ghi đè cài đặt mặc định. Những gì tôi đã làm như sau:
@Configuration
public class WebMvcConfiguration
{
@Bean
public WebMvcConfigurerAdapter faviconWebMvcConfiguration()
{
return new FaviconWebMvcConfiguration();
}
public class FaviconWebMvcConfiguration extends WebMvcConfigurerAdapter
{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.setOrder(Integer.MIN_VALUE);
registry.addResourceHandler("/favicon.ico")
.addResourceLocations("/")
.setCachePeriod(0);
}
}
}
Về cơ bản, tôi ghi đè cái mặc định bằng cách thêm trình xử lý tài nguyên có thứ tự cao nhất bằng cách gọi registry.setOrder (Integer.MIN_VALUE).
Vì giá trị mặc định trong Spring Boot có giá trị thứ tự (Integer.MIN_VALUE + 1), (xem lớp FaviconConfiguration trong https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/ src / main / java / org / springframework / boot / autoconfigure / web / WebMvcAutoConfiguration.java ) trình xử lý của tôi thắng.
Cái này có ổn không? Có cách nào khác (điều gì đó nhẹ nhàng hơn những gì tôi đã làm) không?
CẬP NHẬT
Không ổn. Khi tôi gọi registry.setOrder(Integer.MIN_VALUE)
, thực sự tôi nâng mức ưu tiên của tất cả các trình xử lý tài nguyên. Vì vậy, khi tôi thêm mã sau vào một mã khác WebMvcConfigurerAdapter
, thực tế tất cả yêu cầu http đều được chuyển hướng đến trình xử lý tài nguyên đó, ngăn chặn bất kỳ xử lý động nào bằng mã Java.
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Một giải pháp khác là cần thiết.
CẬP NHẬT
Hiện tại, tôi không thể tìm thấy cách ghi đè chức năng biểu tượng yêu thích mà Spring Boot cung cấp.
Có lẽ có một cách để thêm HandlerMapping
đậu của riêng tôi , nhưng tôi không biết làm thế nào để làm điều đó.
Bây giờ tôi có thể chọn một trong các tùy chọn sau:
- Có một lớp đã
@EnableWebMvc
vô hiệu hóaWebMvcAutoConfiguration
lớp Spring Boot . (Tôi có thể sao chép mã củaWebMvcAutoConfiguration
lớp và xóa chức năng biểu tượng yêu thích) - Từ bỏ quyền tự do đặt tệp favicon vào vị trí trọng tài và đặt nó vào thư mục tài nguyên như chức năng favicon của Spring Boot yêu cầu. Và bỏ qua vấn đề bộ nhớ đệm.
Nhưng không có lựa chọn nào là thỏa đáng.
Tôi chỉ muốn đặt tệp favicon với các tệp web tĩnh của mình (có thể là bất kỳ thư mục nào vì tôi có thể thay đổi gốc tài liệu) và giải quyết vấn đề bộ nhớ đệm.
Tui bỏ lỡ điều gì vậy?
Bất kỳ đề nghị sẽ được đánh giá rất cao.
CẬP NHẬT
BTW, lý do tôi muốn thay đổi vị trí của favicon và các tệp tĩnh khác như sau. Còn bây giờ chủ yếu là vấn đề môi trường phát triển.
Tôi đang xây dựng một ứng dụng web một trang (SPA).
Thư viện / Khung:
- Đối với phía máy chủ, tôi sử dụng Spring. (tất nhiên)
- Đối với phía máy khách (trình duyệt web), tôi sử dụng AngularJS.
Công cụ:
- Đối với phía máy chủ, tôi sử dụng Spring Tool Suite.
- Đối với phía khách hàng, tôi sử dụng WebStorm.
Cấu trúc thư mục chính:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
- src: Nơi các tệp nguồn java Spring của tôi cư trú.
- bin: Nơi Spring Tool Suite đặt đầu ra bản dựng của nó.
- build: Nơi 'gradle build' đặt đầu ra của nó.
- webapp: Nơi chứa các tệp nguồn khách hàng của tôi (.js, .css, .htm và favicon). Vì vậy, đây là thư mục dự án WebStorm. (Tôi có thể thay đổi tên thư mục nếu cần)
Điều tôi muốn là:
- Để có thể sửa đổi và kiểm tra mã máy khách của tôi mà không cần xây dựng lại / khởi động lại ứng dụng máy chủ Spring của tôi. Vì vậy, mã máy khách không được đưa vào tệp jar. Dù sao thì Spring Tool Suite hoàn toàn không tạo một tệp jar (ít nhất là đối với cấu hình hiện tại)
- Để có thể kiểm tra ứng dụng máy chủ Spring của tôi bằng mã máy khách, dễ dàng chuyển đổi giữa đầu ra Spring Tool Suite và đầu ra gradle. Vì vậy, mã máy khách phải có thể truy cập được từ cả ứng dụng máy chủ trong
build
thư mục con (thực tếbuild\libs
) và ứng dụng máy chủ trongbin
thư mục. - Khi tôi sửa đổi mã khách hàng, mã này phải có sẵn ngay lập tức cho trình duyệt web. Vì vậy, trình duyệt không được lưu vào bộ nhớ cache vô thời hạn và phải luôn yêu cầu máy chủ cập nhật.
- Khi được triển khai, mã máy khách phải có thể sửa đổi được mà không cần xây dựng lại / khởi động lại ứng dụng máy chủ. Vì vậy mã máy khách không được đưa vào tệp jar.
Về vấn đề bộ nhớ cache:
Không có setCachePeriod (0) trên addResourceHandlers (), Google Chrome lưu tệp vào bộ nhớ cache vô thời hạn mà không yêu cầu máy chủ cập nhật. Nó thậm chí không kết nối với máy chủ. (Các kỹ sư của Google nói rằng hành vi đó là đúng.) Vì vậy, tất cả những gì tôi có thể làm là xóa bộ nhớ cache của trình duyệt theo cách thủ công. Nó gây thất vọng về môi trường phát triển, và không thể chấp nhận được về môi trường sản xuất.
Mô-đun BTW, express.js trên Node.js cung cấp tiêu đề HTTP mặc định hợp lý để Google Chrome yêu cầu máy chủ cập nhật. Khi tôi xem xét các tiêu đề HTTP mà Spring và express.js tạo ra bằng Fiddler, chúng khác nhau.
Bất kỳ đề xuất để cải thiện môi trường của tôi sẽ được đánh giá cao.
Vì tôi là một người mới bắt đầu mùa Xuân, tôi có thể thiếu một cái gì đó.
CẬP NHẬT
Cuối cùng tôi có một mã làm việc. Nó như sau:
@Configuration
public static class FaviconConfiguration
{
@Bean
public SimpleUrlHandlerMapping myFaviconHandlerMapping()
{
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Integer.MIN_VALUE);
mapping.setUrlMap(Collections.singletonMap("/favicon.ico",
myFaviconRequestHandler()));
return mapping;
}
@Autowired
ApplicationContext applicationContext;
@Bean
protected ResourceHttpRequestHandler myFaviconRequestHandler()
{
ResourceHttpRequestHandler requestHandler =
new ResourceHttpRequestHandler();
requestHandler.setLocations(Arrays
.<Resource> asList(applicationContext.getResource("/")));
requestHandler.setCacheSeconds(0);
return requestHandler;
}
}
Chú ý tên các loại đậu. Tôi đã thêm 'của tôi' để tránh đụng độ tên.
Bản thân ngữ cảnh ứng dụng Autowiring có vẻ khó xử, nhưng nó là cần thiết để bắt chước mã trong org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()
.
Bây giờ tôi có một trình xử lý biểu tượng yêu thích không gặp sự cố bộ nhớ đệm và tôi có thể đặt tệp biểu tượng yêu thích ở bất cứ đâu tôi muốn.
Cảm ơn.
classpath:/static
bất kỳ nơi nào nữa). (Đó là lý do tại sao sự hỗ trợ favicon trong Boot là trong HandlerMapping riêng của mình tôi nghĩ.)