FileNotFoundException with ObjectMapper in JSON/REST - java

I have created a class that provides a method to obtain via REST a JSON object that should be then deserialised as LinkedHashMap. The method is the following:
#Override
public LinkedHashMap refreshStatus(String metricType, String metricPeriod) {
ObjectMapper mapper = new ObjectMapper();
LinkedHashMap<String,String> map = null;
try {
map = mapper.readValue(new File("http://localhost:8081/Metrics/Stats/JSONP/ReceiveData/"+metricType+"/"+metricPeriod+"/?callback="), LinkedHashMap.class);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
When I enter in the browser the URL with some specific parameters, i.e.
http://localhost:8081/Metrics/Stats/JSONP/ReceiveData/Totals/All/?callback=
I get a proper JSON object:
{"Boxes":"8","Contracts":"23","Updates":"1","Deactivations":"4","ActiveBoxes":"33","InactiveBoxes":"1","PendingInstallationsContracts":"70","Alerts":"626","PercentsBoxInstalled":"100.0%","Miles":"0"}
However when I run the application and the method is invoked, I get a FileNotFoudException:
java.io.FileNotFoundException: http:/localhost:8081/Metrics/Stats/JSONP/ReceiveData/Totals/All/?callback= (No such file or directory)
Does anyone know where the problem may be? Thanks in advance!

This file indeed cannot be found on your computer. You try to create file objects correspoding to real file in your local file system and provide URL as an argument instead of file system path.
You actually want to perform HTTP GET, i.e. do something like the following.
urlString = "http://localhost:8081/Metrics/Stats/JSONP/ReceiveData/Totals/All/?callback=";
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
map = mapper.readValueconn.getInputStream();

Related

Spring Boot jar saving to existing file

I want to save data with jackson to existing file (update it) but it won't work when I run my project from jar.
I need to use json as "database" (I know it's pretty stupid but that's for a school project) and to do it I load and save all the data when I do any of CRUD operations. It's working fine when I run it with IDE but when I tried as a jar it had a problem with reading file from ClassPathResource.
So I have this method to save changes to file:
private List<Item> items;
private ObjectMapper mapper;
private ObjectWriter writer;
public void saveData() {
mapper = new ObjectMapper();
writer = mapper.writer(new DefaultPrettyPrinter());
try {
writer.writeValue(new ClassPathResource("items.json").getFile(), items);
} catch (IOException e) {
e.printStackTrace();
}
}
And it works just fine when i run this through IntelliJ but it won't work when I run it as a jar.
I found a solution to loading the data by using InputStream from this question and method looks like this:
public void loadData() {
mapper = new ObjectMapper();
try {
ClassPathResource classPathResource = new ClassPathResource("items.json");
InputStream inputStream = classPathResource.getInputStream();
File tempFile = File.createTempFile("test", ".json");
FileUtils.copyInputStreamToFile(inputStream, tempFile);
System.out.println(tempFile);
System.out.println(ItemDao.class.getProtectionDomain().getCodeSource().getLocation().getPath().toString());
items = mapper.readValue(tempFile, new TypeReference<List<Item>>() {
});
} catch (IOException e) {
items = null;
e.printStackTrace();
}
}
But I still have no idea how to actually save changes. I was thinking about making use of FileOutputStreambut I achieved nothing.
So I want to get this working in jar file and be able to save changes to the same file, thanks for help in advance!
when you want to do read/write operations, it is better keep the file outside of the project. when running the jar, pass file name with path as an argument. like -DfileName=/Users/chappa/Documents/items.json etc. This way, you have absolute path, and you can perform read/write operations on it
if you are using java 1.7 or above, use below approach to write data.
To read data, you can use jackson api to load the json file as is.
Path wipPath = Paths.get("/Users/chappa/Documents/items.json");
try (BufferedWriter writer = Files.newBufferedWriter(wipPath)) {
for (String record : nosRecords) {
writer.write(record);
}
}
Just in case if you want to read json using IO streams, you can use below code
Path wipPath = Paths.get("/Users/chappa/Documents/items.json");
try (BufferedReader reader = Files.newBufferedReader(wipPath)) {
String line=null;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
}

Can't fetch expanded URL from a given shortened URL

I am given a shortened url and I want to get the expanded form. The below java function is used to achieve this.
public String expand(String shortenedUrl){
URL url = null;
try {
url = new URL(shortenedUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
// open connection
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
} catch (IOException e) {
e.printStackTrace();
}
// stop following browser redirect
httpURLConnection.setInstanceFollowRedirects(false);
// extract location header containing the actual destination URL
String expandedURL = httpURLConnection.getHeaderField("Location");
httpURLConnection.disconnect();
return expandedURL;
}
The code works fine in Eclipse but the same doesn't work in android.
String expandedURL = httpURLConnection.getHeaderField("Location");
The above line throws java.lang.RuntimeException: Unable to start activity ComponentInfo. And the error is pointed to the above line. If I remove the above line no error is encountered. Even I am not able to use getResponseCode() function.
int status = 0;
try {
status = httpURLConnection.getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
This piece of code also has the same problem. works in eclipse but not in android.
Any kind of help will be greatly appreciated.
Edit: The code using above function is,
ExpandUrl expandUrl = new ExpandUrl();
String expandedUrl = expandUrl.expand(shortenedUrl);
Note: The function expand is defined inside the class ExpandUrl.
Well, the code works in Eclipse but not in android. The reason is that you are doing it in Main thread and blocking it. Android wouldn't allow you to do so and throw runtime error.
I have tried to implement your code using AsyncTask in android. It works fine.
Give it a try.
To know more about AsyncTask follow: Android Documentation on AsyncTask
Good Luck!

Nanohttpd serve multiple files

Using nanohttpd I can select a chosen file and start a server to serve that one file.
Is it possible to serve a list of lot of files?
That is, I have lot of files in sd card and I want to serve the selected ones. So how to give an array of file paths of those files and generate and return URL for them, so that I can access them from network.
Not an HTML page which lists all those files and folders.
I have gone through this, this is not what I am referring to. In this it it just lists the root folder and lists them all in a HTML page, for a user to view/select. Not what I am after.
Just an array of server URLs for a selected, chosen list of files in sdcard, which I can then use programmatically.
As of now I have this
protected void onCreate(Bundle savedInstanceState) {
...
server = new Mp3Server();
try {
server.start();
} catch(IOException ioe) {
Log.w("Httpd", "The server could not start.");
}
Log.w("Httpd", "Web server initialized.");
}
...
...
public class Mp3Server extends NanoHTTPD {
public Mp3Server() {
super(8089);
}
#Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parameters,
Map<String, String> files) {
String answer = "";
FileInputStream fis = null;
try {
fis = new FileInputStream("/storage/C67A-18F7/Music/music.mp3");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return newChunkedResponse(Status.OK, "audio/mpeg", fis);
}
}
Or do I have to pass the chosen file and start/stop server each time for each file? But this sounds inefficient.

Exception after reading values from jsp page

I am inserting values into database but I am getting UIException here is my code sample,
public void createTeacherInfo(HttpServletRequest request) {
try{
TeacherInfo teacherInfo= new TeacherInfo();
request.getParameter("flowName");
DateFormat df = new SimpleDateFormat("dd-mm-yyyy");
String tId= request.getParameter("teacherId");
teacherInfo.setTeahcerId(Integer.parseInt(tId));
//teacherInfo.setTeahcerId(Integer.parseInt(request.getParameter("teacherId")));
teacherInfo.setTeacherName(request.getParameter("teacherName"));
/*teacherInfo.setDob(df.parse(request.getParameter("dob")));
teacherInfo.setDoj(df.parse(request.getParameter("doj")));*/
teacherInfo.setTeacherEducation(request.getParameter("education"));
teacherInfo.setPreviousEmployeDetails(request.getParameter("prevdetails"));
//teacherInfo.setYearOfExper(Integer.parseInt(request.getParameter("experience")));
teacherInfo.setTeahcherPhoto(request.getParameter("photo"));
teacherInfo.setTeacherEmail(request.getParameter("email"));
System.out.println(tId);
System.out.println("TeacherId");
pupilInfoManagementBusinessService.createTeacherInfo(teacherInfo);
}catch (BusinessException e) {
webLayerLogger.error(CommonUtils.getStackTrace(e));
throw new UIException(e,UIMessageHelper.getLocalValue("exception while Inserting data"));
}
}
In this method after reading all values it will go to service method , Here is service class method,
#Override
public void createTeacherInfo(TeacherInfo teacherInfo) throws BusinessException {
try {
pupilInfoManagementDataService.createTeacherInfo(teacherInfo);
}catch (Exception e) {
businessServiceLogger.error(CommonUtils.getStackTrace(e));
throw new BusinessException(this.getClass(), e, e.getMessage());
}
}
My problem is values are reading but not inserting to database. Please help me in this .
I'll bet the html form for this includes a file upload for the photo. When a form includes a file upload, then request.getParameter will not work any longer (the values will always be null). When you do a file upload you have to use Apache Commons File Upload library to retrieve the parameters from the request, or you can use request.getPart (if you are on the latest version of your servlet container).

Trasferring files and data with Jersey

I'm trying to develop some rest services with Jersey to upload and download files (something like a file manager). If my services produce/consume only File class as "application/octet-stream", like in the code below, they work.
#GET
#Produces("application/octet-stream")
public File getFile(String id) {
try {
File file = new File(System.getProperty("user.home"), id);
return file;
} catch (FileNotFoundException ex) {
Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
But if I try to transfer a custom object that contains a File field and some other data (FileEnvelope in the sample) I obtain an error.
#GET
#Produces("application/octet-stream")
public FileEnvelope getXml(String id) {
try {
File file = new File(System.getProperty("user.home"), id);
FileEnvelope fileEnvelope = new FileEnvelope(file, "text");
return fileEnvelope;
} catch (FileNotFoundException ex) {
Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
The error is
Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class com.mycompany.restdemo.FileEnvelope, and Java type class com.mycompany.restdemo.FileEnvelope, and MIME media type application/octet-stream was not found
Where I'm wrong? Is this the right way to manage this case? My client could not be a "Jersey client".
Jersey has no idea how to serialize your domain object into an octet-stream unless you tell it how. In this case if you want to include extra information beyond the file data you should consider how the client should be expected to read it. You could:
Embed the information directly in the octet stream by creating your own MessageBodyWriter. The client would need to know where to look for this information in the resulting file.
Include the information as part of the HTTP response header using ResponseBuilder. The client would just need to know which response headers to check for the information.
You can send different types of data in one message using multipart/* media types. For example this article shows how: http://aruld.info/handling-multiparts-in-restful-applications-using-jersey/

Categories

Resources