【问题标题】:Use Spring to inject text file directly to String使用 Spring 将文本文件直接注入 String
【发布时间】:2012-11-24 06:11:45
【问题描述】:

所以我有这个

@Value("classpath:choice-test.html")
private Resource sampleHtml;
private String sampleHtmlData;

@Before
public void readFile() throws IOException {
    sampleHtmlData = IOUtils.toString(sampleHtml.getInputStream());
}

我想知道的是,是否可以不使用 readFile() 方法并让 sampleHtmlData 注入文件的内容。如果不是,我只能忍受这个,但这将是一个不错的捷径。

【问题讨论】:

    标签: java spring inject


    【解决方案1】:

    从技术上讲,您可以使用 XML 以及工厂 bean 和方法的笨拙组合来做到这一点。但是,当您可以使用 Java 配置时,何必费心呢?

    @Configuration
    public class Spring {
    
        @Value("classpath:choice-test.html")
        private Resource sampleHtml;
    
        @Bean
        public String sampleHtmlData() {
            try(InputStream is = sampleHtml.getInputStream()) {
                return IOUtils.toString(is, StandardCharsets.UTF_8);
            }
        }
    }
    

    请注意,我还使用 try-with-resources 习语关闭了从 sampleHtml.getInputStream() 返回的流。否则你会得到内存泄漏。

    【讨论】:

    • 我想我会试一试,谢谢,但不幸的是我正在编译到 Java 6,所以我不能使用 try/with :(
    • 谢谢。我没有使用 IOUtils,而是使用 new String(Files.readAllBytes(sampleHtml.getFile().toPath()));
    • 我建议使用StreamUtils.copyToString(in);,而不是使用 IOUtils:这与 spring 捆绑在一起,所以无论如何你都有这个方法,与@EvanHu 的建议相反,我认为如果你的资源是不在文件系统中。
    【解决方案2】:

    据我所知,没有内置功能,但你可以自己做,例如像这样:

    <bean id="fileContentHolder">
      <property name="content">
        <bean class="CustomFileReader" factory-method="readContent">
          <property name="filePath" value="path/to/my_file"/>
        </bean>
       </property>
    </bean>
    

    其中 readContent() 返回从 path/to/my_file 上的文件读取的字符串。

    【讨论】:

      【解决方案3】:

      如果您希望每次注入减少到一行,您可以添加注释和条件转换器。这还将在 IntelliJ 中保留 ctrl-click 导航和自动完成功能。

      @SpringBootApplication
      public class DemoApplication {
      
          @Value("classpath:application.properties")
          @FromResource
          String someFileContents;
      
          @PostConstruct
          void init() {
              if (someFileContents.startsWith("classpath:"))
                  throw new RuntimeException("injection failed");
          }
      
          public static void main(String[] args) {
              SpringApplication.run(DemoApplication.class, args);
          }
      
          DemoApplication(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
              // doing it in constructor ensures it executes before @Value injection in application
              // if you don't inject values into application class, you can extract that to separate configuration
              environment.getConversionService().addConverter(new ConditionalGenericConverter() {
                  @Override
                  public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
                      return targetType.hasAnnotation(FromResource.class);
                  }
      
                  @Override
                  public Set<GenericConverter.ConvertiblePair> getConvertibleTypes() {
                      return Set.of(new GenericConverter.ConvertiblePair(String.class, String.class));
                  }
      
                  @Override
                  public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
                      try (final var stream = resourceLoader.getResource(Objects.toString(source)).getInputStream()) {
                          return StreamUtils.copyToString(stream, StandardCharsets.UTF_8);
                      } catch (IOException e) {
                          throw new IllegalArgumentException(e);
                      }
                  }
              });
          }
      }
      
      @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      @interface FromResource {
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-16
        • 2017-08-21
        • 1970-01-01
        • 2011-06-02
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多