Simple Soap service running on Axis engine on Tomcat v9.0 server needs to read and write to XML files. I developed soap service in Eclipse like a dynamic web project, so the XML files are in the WebContent->WEB-INF->resources->...
When i read the files everything works fine, but when i want to write to the files i get InvocationTargetException. Since i read files normaly, I guess that i'm not opening stream as i should when i write in the files, so can anyone guide me how to do this properly?
Here's the method for reading the file, and this WORKS:
public Station deserialization(String name, String path) {
Station s=null;
try {
URL url=getClass().getClassLoader().getResource(path+File.separator+name+".xml");
InputStream is=url.openStream();
XMLDecoder decoder = new XMLDecoder(is);
s=(Station) decoder.readObject();
decoder.close();
} catch (Exception e) {
Main.LOGGER.info("Station deserializaton was not successful!");
}
return s;
}
and here's the method for writing into the file, this DOESN'T work:
public boolean serialize(Station s, String path) {
try {
URL url=getClass().getClassLoader() .getResource(path+File.separator+s.getName()+".xml");
URLConnection con=url.openConnection();
con.setDoOutput(true);
OutputStream out=con.getOutputStream();
XMLEncoder encoder = new XMLEncoder(out);
encoder.writeObject(s);
encoder.close();
} catch (Exception e) {
Main.LOGGER.info("Station serialization was not successful!");
return false;
}
return true;
}
My real question here is how come the same principle work when reading the file and doesn't work with writing into the file? File paths are the same in both methods.
I found what was the problem. Turns out you can read files with URL, but you cant write to URL or URLConnection. I had to use FileOutputStream for writing into the files:
XMLEncoder encoder=new XMLEncoder(new FileOutputStream("file_path"));
You can also keep the files in WebContent->WEB-INF (if you develop web service in Eclipse) if you want web service to use them, becuse it then makes copies of them.
Just keep an eye on the path that you are providing, double check if it is the right one!
Related
I've recently inherited a Java API and am having trouble with file uploads. Unfortunately, Java isn't a language I have much experience in so I'm a bit stumped by this.
The MultiPartFile is being received ok, and I can find the file in the temp directory, but when I try to use File.transferTo() to create the final file I just get the below error;
java.nio.file.NoSuchFileException: C:\Users\myUser\AppData\Local\Temp\undertow3706399294849267898upload -> S:\Dev\PolicyData\Temp.xlsx
As I mentioned the temp undertow file exists, and the directory on the S drive also exist, (but there's no Temp.xlsx as my understanding is this should be created by transferTo()). Any solutions I've found to this problem so far are resolved using absolute file paths.
This is a simplified version of the code but the error remains the same.
SpringBoot framework is "1.5.3.RELEASE", running Java 1.8.0_131
ResponseEntity handleFileUpload(#RequestPart(name = "file") MultipartFile file, #PathVariable Long stageFileTypeId) {
if (!file.isEmpty()) {
try {
String filePath = "S:\\Dev\\PolicyData\\Temp.xlsx";
log.info("Upload Path = {}", filePath);
File dest = new File(filePath);
file.transferTo(dest);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(filePath));
}
catch (Exception ex) {
log.error("An error has occurred uploading the file", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
else {
log.error("An error has occurred, no file was received");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
If you need any more information please let me know.
Thanks,
Neil
The API for MultipartFile is a bit tricky. The transferTo(File) method javadoc states that (bold are mine):
This may either move the file in the filesystem, copy the file in the
filesystem, or save memory-held contents to the destination file. If
the destination file already exists, it will be deleted first.
If the target file has been moved in the filesystem, this operation
cannot be invoked again afterwards. Therefore, call this method just
once in order to work with any storage mechanism.
It seems that the Undertow implementantion already called it to move the in-memory uploaded file to "C:\Users\myUser\AppData\Loca\Temp\undertow3706399294849267898upload" so another transferTo is failing.
I came across the same problem using javax.servlet.http.Part in a Wildfly containter with Undertow.
If you are using Spring framework >= 5.1, you could try the Multipart.transferTo(Path) method, using dest.toPath()
Or you can copy from the inputStream, with something like this:
try (InputStream is = multipartFile.getInputStream()) {
Files.copy(is, dest.toPath());
}
I'm working on a simple app and im trying to understand how to read from a json file using a json parser. I wrote a simple json file and put it in one of my directories. Then I used right clock to get the path, and wrote the following code:
public void myParser() {
JSONParser parser = new JSONParser();
String path = "C:\\Users\\My Name\\IntelliJIDEAProjects\\Intereview\\app\\src\\main\\res\\Data\\dataStructures.json";
try{
JSONArray topics = (JSONArray)parser.parse(new FileReader(path));
for(int i=0;i<topics.length();i++) {
JSONObject object = topics.getJSONObject(i);
String title = object.optString("title").toString();
Log.i(TAG,title);
}
}
catch(JSONException e) {
Log.e("Internal Problem", e.getMessage());
} catch (ParseException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
from some reason, i get this error when running the app:
java.io.FileNotFoundException: C:\Users\My Name\IntelliJIDEAProjects\Intereview\app\src\main\res\Data\dataStructures.json: open failed: ENOENT (No such file or directory)
what could be the reason behind that? i've been working on this for the past few hours and I just can't figure it out..
Thanks
You have android on this question, so I assume that you are trying to write an Android app. If so, this will not work:
String path = "C:\\Users\\My Name\\IntelliJIDEAProjects\\Intereview\\app\\src\\main\\res\\Data\\dataStructures.json";
My guess, based on that path, is that you are trying to package a JSON file with your app. In that case, you cannot create random directories under res/ either. Even if this JSON file were in a proper res/ directory (e.g., res/raw/), you cannot access it via a FileReader. It is a file on your development machine. It is not a file on the Android device.
Your two main options are:
Move that JSON file from res/Data/ into res/raw/. Then, use getResources().openRawResource(R.raw.dataStructures) to get an InputStream on the JSON.
Move that JSON file from res/Data/ into assets/. Then, use getAssets().open("dataStructures.json") to get an InputStream on the JSON.
Note that getResources() and getAssets() are methods on Context and its subclasses, such as Activity.
This appears when the file isn't there...
Check the spelling of your pathname (intereview?) and... check if the file is there.
you need to put json inside the assets folder.
In the perspective window open the Project Perspective.
Create the directory inside your android_test/test folder with name assets depending upon where you need the JSON response
Now simple put your JSON file inside the assets folder
And call your JSON by simply calling their single name like xyz.json
I am using Kryo to save binary files of user data. The user can open one of their files in my application. I'm not sure if I have a clean approach to detecting whether they tried to open a file of some other type.
Right now, I'm writing a simple FileHeader object to the file before the user's data. The file header has info about what version of the app saved the file.
public void write (UserProject project, File file) throws FileNotFoundException {
OutputStream outputStream = new DeflaterOutputStream(new FileOutputStream(file));
Output output = new Output(outputStream);
kryo.writeObject(output, new FileHeader());
kryo.writeObject(output, project);
output.close();
}
So when I load a file, I can try to deserialize the file header and the user project and catch any Exception that might occur. But doing a catch-all block could hide certain issues I could perhaps react to in a more elegant way that simply showing the user an error no matter the exception. Here's what I'm doing now:
public Project read (File file) throws FileNotFoundException, FileVersionException, UnreadableException {
InputStream inputStream = new InflaterInputStream(new FileInputStream(file));
Input input = new Input(inputStream);
try {
FileHeader fileHeader = kryo.readObject(input, FileHeader.class);
if (fileHeader.fileVersion > CURRENT_FILE_VERSION)
throw new FileVersionException(/* */);
Project project = kryo.readObject(input, Project.class);
return project;
} catch (Exception e){
if (DEBUG) e.printStackTrace();
throw new UnreadableException(e); //caller will show user error msg
} finally {
input.close();
}
}
I suppose there's also a very tiny (infinitesimal?) chance that some file actually loads without throwing an exception, in which case a very unexpected error could happen elsewhere in my application. Not sure if I should worry about this...a user should not expect to open an incorrect file type and have it work correctly.
You could use magic numbers, a set of bytes that describes the type of file. Like .jpg, .pdf, .wav, etc. all have a few bytes at the beginning of each file, so even if these types are saved with different extensions you can check to see if the file's magic number is OK.
Magic Number Description
However, if you're serializing and deserializing you may have to tack on some additional data to the file after serializing and remove it before deserializing.
So what I am trying to achieve is reading the contents of a .txt file from a url:
BufferedReader reader = null;
File f = new File ("www.website.com/filename.txt");
if (f.exists()) {
try {
reader = new BufferedReader(new FileReader(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = "";
try {
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Even though I have content in the .txt file (only one line), when I print the line nothing shows up. Is reading a file from a URL or from your hard drive different, or am I doing something wrong?
The File class is for files on a "normal" file system (usually local, but potentially networked) - not URLs. Basically it's for the sort of file you can use (e.g. read or edit) directly on a command line, with no HTTP involved1.
That's what the URL class is for. So you can either use that (with URLConnection) or use a dedicated HTTP 3rd party library, such as the Apache HttpClient library.
1 I'm sure there are some shells which allow the use of URLs as if they were local filenames, but I'm talking about a more traditional approach.
I tried own my own and this worked...
URL urlObj=new URL("http://www.example.com/index.html"); //This can be any website' index.html or an available file
//we basically get HTML page/file
Scanner fGetter=new Scanner(urlObj.openStream());
while(fGetter.hasNext()){
System.out.println(""+fGetter.nextLine());
}
And I think "example.com" can be used without any legal issues :)
I don't actually know but I don't think you can read a file from a URL like that. You need to send a HTTP GET request to that url to read the information in.
See object HttpURLConnection.
http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html
I hava a tomcat java web application. I want to create a file to store some json data in it. How do I create this file and where will this file be created?
public void insert(UserProfile profile) {
JSONObject jsUser = profile.asJSONObject();
try {
String path = profile.getUsername()+".json";
FileWriter fileWriter = new FileWriter(path);
fileWriter.write(jsUser.toJSONString());
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
How do I create this file ...
Use the standard Java I/O libraries to create and write the file; e.g. you could use a FileWriter.
... and where will this file be created?
It is entirely up to you to decide where you want the file to be created.
However, you need to beware of the possibility that someone might trash your web service by causing it to fill up the file system ... or by causing it to write stuff on top of some (important) existing file. You need a good strategy for dealing with these concerns, but that will depend on the purpose of these files, and the circumstances under which they are written.