Setting a resource for Spring Batch reader from file system - java

I'd like to adjust my code to make the Spring Batch reader to read the resource file not from class path, but from the file system (like C:\inputData.xml). Is there any way, how to make it? My current code looks like this and reads given xml file from resources folder just fine:
#Bean
ItemReader<FamilyBatchEntity> xmlFamilyFileItemReader() {
StaxEventItemReader<FamilyBatchEntity> xmlFileReader = new StaxEventItemReader<>();
xmlFileReader.setResource(new ClassPathResource("inputData.xml"));
xmlFileReader.setFragmentRootElementName("Familiendetails");
Jaxb2Marshaller insurantMarshaller = new Jaxb2Marshaller();
insurantMarshaller.setClassesToBeBound(FamilyBatchEntity.class);
xmlFileReader.setUnmarshaller(insurantMarshaller);
return xmlFileReader;
}

Change your ClassPathResource to a FileSystemResource and pass in the path. You can read more about the FileSystemResource in the documentation here: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/io/FileSystemResource.html

Related

How to pass property file from spring config server to YAML reader?

I am currently moving my property files to spring-config-server. I have created a config server and it is running on my localhost(http://localhost:8080).
In my application I can able to access the properties from config server for different environments like local and dev. But in my code I was reading one of the property file by Yaml reader for other mappings.
The following the code for reader:
Yaml yaml = new Yaml();
InputStream inputStream = clazz
.getClassLoader()
.getResourceAsStream("application-myprops.yml");
MyPropsYaml obj = yaml.loadAs(inputStream, MyPropsYaml.class);
By executing this I am getting the following error:
org.yaml.snakeyaml.error.YAMLException: java.io.IOException: Stream closed
at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:218)
at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:176)
at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:171)
at org.yaml.snakeyaml.reader.StreamReader.peek(StreamReader.java:126)
at org.yaml.snakeyaml.scanner.ScannerImpl.scanToNextToken(ScannerImpl.java:1198)
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:308)
at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:248)
at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:213)
at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:165)
at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:155)
at org.yaml.snakeyaml.composer.Composer.getSingleNode(Composer.java:141)
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:151)
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:491)
at org.yaml.snakeyaml.Yaml.loadAs(Yaml.java:484)
I have tried by passing the config server url as well like this, but it didn't work
Yaml yaml = new Yaml();
InputStream inputStream = clazz
.getClassLoader()
.getResourceAsStream("http://localhost:8080/application-myprops.yml");
MyPropsYaml obj = yaml.loadAs(inputStream, MyPropsYaml.class);
I dont want to place application-myprops.yml in my application. It should be in my config server. How can I make it work like that.
Thanks in advance!

Deployed WAR can't access a file

I have a spring application, and i'm trying to access a json file with the following code :
try (FileReader reader = new FileReader("parameters.json")) {
Object obj = jsonParser.parse(reader);
parameterList = (JSONArray) obj;
}
I have put the parameter.json file in the project folder and I'm accesing the file data from an angular app through a rest api, and that works fine when I run the application on local machine, but when I deploy the war file on tomcat, my application can't load the file, should I put parameter.json file somewhere else on tomcat or what is the best solution for it.
Your question states you are attempting to access a file called parameter.json, while your code excerpt shows parameters.json. Perhaps that discrepancy indicates a typo in your source code?
If not, there are various ways to access a file from the classpath in Spring, with the first step for each being to ensure the file is in the project's src/main/resources directory.
You can then use one of the Spring utility classes ClassPathResource, ResourceLoader or ResourceUtils to get to the file. The easiest approach, though, may be to put your properties in a .properties file (default file name application.properties) and access the values using Spring's #Value annotation:
#Value("${some.value.in.the.file}")
private String myValue;
You can use other file names as well by utilizing #PropertySource:
#Configuration
#PropertySource(value = {"classpath:application.properties",
"classpath:other.properties"})
public class MyClass {
#Value("${some.value.in.the.file}")
private String myValue;
...
}
Make sure your parameters.josn filename is exactly same in the code.
Move you parameters.json file in the resources folder and then use the classpath with the filename.
try (FileReader reader = new FileReader("classpath:parameters.json")) {
Object obj = jsonParser.parse(reader);
parameterList = (JSONArray) obj;
}
Try to put the file under resources folder in your spring project. You should be able to access the file from that location.
FileReader is looking for a full-fledged file system like the one on your computer, but when your WAR is deployed, there just isn't one, so you have to use a different approach. You can grab your file directly from your src/main/resources folder like this
InputStream inputStream = getClass().getResourceAsStream("/parameters.json");

How to load resource from an absolute path?

I am using ff4j like this:
FF4J ff4j = new FF4J("config.xml");
Internally, FF4J calls getClass().getClassLoader().getResourceAsStream("config.xml").
I want to be able to choose the config.xml location at deployment time (for example, /etc for linux).
How can I achieve that, without having to hardcode an absolute path? Is it possible to set the JVM / tomcat to look for the file in /etc for example? Or maybe there's another way to achieve what I want with FF4J?
As creator of FF4j I would add a couple of solutions.
Before 1.8.9
File configFile = new File("/tmp/ff4j.xml");
FileInputStream fis = new FileInputStream(configFile);
FF4j ff4j = new FF4j(fis);
Since 1.8.9
File configFile = new File("/tmp/ff4j.xml");
FileInputStream fis = new FileInputStream(configFile);
FF4j ff4j= new FF4j(new XmlParser(), fis);
As such you can now also import Yaml or properties files. (thinking about configMap in K8s world here). More samples here

MockMultipartFile not working in real environment, as it is available in test package of spring. Is there any workaround for this?

I have a file on my local disk, I want to convert that file to multipart file as I need to upload this file to another server. I am converting file to multipart file using MockMultipartFile, but it is not working as this package is only available in the test environment
I am trying to use CommonsMultipartFile instead of MockMultipartFile, but CommonsMultipartFile constructor needs an object of file item. I am not able to utilize that constructor
Using MockMultipartFile::
FileInputStream fileInputStream = new FileInputStream(unzippedFile);
return new MockMultipartFile(FILE_STRING, unzippedFile.getName(), MULTIPART_FORM_DATA_VALUE, IOUtils.toByteArray(fileInputStream))
Using CommonsMultipartFile::
DiskFileItem diskFileItem = new DiskFileItem(FILE_STRING, MULTIPART_FORM_DATA_VALUE, false, unzippedFile.getName(), (int) unzippedFile.length(), unzippedFile.getParentFile());
diskFileItem.getOutputStream();
MultipartFile multipartFile = new CommonsMultipartFile(diskFileItem);
I expect CommonsMultipartFile constructor to take diskFileItem, but it is giving an error

how to read a file from resources folder in properties file

I have a file under resources folder src/test/resources/file.xml
and another under src/test/resources/test.properties. I want to set a property in properties file to point to file.xml. How can I achieve this?
Say I have a property
test.file = file.xml
and my java class reads the file as follows:
File cert = new File(fileName); // fileName is the value of test.file
This does not work however.
You can use Properties class to read and write to config files.
Firstly, you need to find the relative path for the resources using
below steps
Secondly, you can configure and load the test properties file
Finally, read the property value and append with the resource
directory
Code:
String rootDirectory=System.getProperty("user.dir");
String resourceDirectory=rootDirectory+"src/test/resources/";
//Configure property File
Properties properties = new Properties();
properties.load(new FileInputStream(resourceDirectory+"test.properties"));
PropertyConfigurator.configure(properties);
//To get the property value
String tempFileName=properties.getProperty("test.file");
//filename Needs to be changed as below
File cert = new File(resourceDirectory+tempFileName);

Categories

Resources