Используйте Spring для вставки текстового файла непосредственно в String

Так что у меня есть это

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

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

Я хотел бы знать, возможно ли не использовать метод readFile() и вводить sampleHtmlData с содержимым файла. Если нет, мне просто придется жить с этим, но это было бы хорошим сокращением.


person rozner    schedule 06.12.2012    source источник


Ответы (3)


Технически вы можете сделать это с помощью XML и неудобной комбинации фабричных компонентов и методов. Но зачем беспокоиться, если можно использовать конфигурацию 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);
        }
    }
}

Обратите внимание, что я также закрываю поток, возвращаемый sampleHtml.getInputStream(), с помощью идиомы try-with-resources. В противном случае вы получите утечку памяти.

person Tomasz Nurkiewicz    schedule 06.12.2012
comment
Я думаю, что попробую, спасибо, но, к сожалению, я компилирую в Java 6, поэтому я не могу использовать try/with :( - person rozner; 06.12.2012
comment
Спасибо. Вместо использования IOUtils я использую new String(Files.readAllBytes(sampleHtml.getFile().toPath())); . - person Evan Hu; 18.01.2015
comment
Вместо использования IOUtils я предлагаю использовать StreamUtils.copyToString(in);: это связано с Spring, поэтому у вас все равно есть этот метод, и, в отличие от предложения @EvanHu, я думаю, что это более совместимо, если ваши ресурсы не находятся в файловой системе. - person yankee; 25.07.2017

Насколько мне известно, для этого нет встроенных функций, но вы можете сделать это самостоятельно, например. так:

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

Где readContent() возвращает строку, которая считывается из файла по пути/в/мой_файл.

person abalogh    schedule 06.12.2012

Если вы хотите уменьшить его до одной строки на инъекцию, вы можете добавить аннотацию и условный преобразователь. Это также сохранит навигацию по нажатию Ctrl и автозаполнение в IntelliJ.

@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 {
}
person Marcin Wisnicki    schedule 22.07.2021