1

Sorry if my question is very simple- Servers confuse me to no end!

I am currently writing a java program that generates a file, which I read and parse later on. I have it all working on my local machine but problems arise when I deploy it to the web.

Can I save a file on server using FileOutputStream?

This question suggests the correct way to do this is to use request.getServletContext().getRealPath("/")

However, as my code doesn't extend/implement Servlet or HttpServletRequest (and I don't think I want them to?)

What is the correct way to do this?

would really appericiate guidance.

My code:

@Path("/circleRoute")
public class circularRoute {


    @GET
    @Produces("application/xml")
    public String routeAsXML() {
        return "<GeneratedRoute> </GeneratedRoute>";
    }

    @Path("{distance}/{lat}/{lon}/{angle}")
    @GET
    @Produces("application/xml")
    public String routeAsXML(@PathParam("lat") double lat,
            @PathParam("lon") double lon,
            @PathParam("distance") double distance,
            @PathParam("angle") int angle) {
        try {
            Search.generateData(lat, lon);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("Couldn't generate data");
            e.printStackTrace();
        }


////////This is the important line I want to fix//////////////////////////
             Search search = new Search(new
         File(System.getProperty("user.home"),"route.xml"));
//////////////////////////////////////////////////////////////////////////






        long start = search.findClosestNode(lat, lon);
        MyNode startNode = search.getParse().getAllNodes().get(start);
        search.setStartNode(startNode);
        BoyleHawesCycle routeCreator = new BoyleHawesCycle(startNode,
                search.getParse(), distance, angle);
        routeCreator.getCircularPoints();

        String toReturn = "<GeneratedRoute>";
        while (!routeCreator.route.isEmpty()) {
            SearchNode next = routeCreator.route.poll();
            toReturn += ("<Node><lat>" + next.getLat() + "</lat><lon>"
                    + next.getLon() + "</lon></Node>");
        }
        toReturn += "<length>" + routeCreator.getRouteLength() + "</length>";
        toReturn += ("</GeneratedRoute>");
        System.out.println(toReturn);
        return toReturn;
    }
}
Matt Boyle
  • 385
  • 1
  • 6
  • 25
  • Why are you saving it to a `File`? Generally, you want to stream your response to the client. What *exactly* is `Search`? – Elliott Frisch Feb 05 '15 at 22:40
  • It is a custom search algorithm I implemented. I do it and print it out in xml and then my app parses the xml. – Matt Boyle Feb 05 '15 at 22:41
  • That's still not an explanation of why you're saving it to a `File`... Also, printing it to xml to then parse that xml sounds redundant to me. – Elliott Frisch Feb 05 '15 at 22:42
  • Happy to take any advice on a better way to approach it. I basically download a segment of map data to do the search on (which is the route.xml here). print it and my app can use it. You can see what is produced here http://ec2-54-68-140-145.us-west-2.compute.amazonaws.com:8080/RunnersToolboxWebService2/runnerstoolbox/getroute/5/52.4447400/-1.9292630 – Matt Boyle Feb 05 '15 at 22:44
  • Let's see the class `Search`. My guess is that it could be re-factored trivially to work with streams, as I said in my first comment. – Elliott Frisch Feb 05 '15 at 23:30
  • Would it be possible to address my original question as to how I would save a file to a server and access it correctly? I feel we are getting more towards a code review here – Matt Boyle Feb 05 '15 at 23:31
  • Sure. Configure your server to allow File access. Normally that's disallowed by the [Security Manager](http://tomcat.apache.org/tomcat-6.0-doc/security-manager-howto.html) because it's a possible attack vector. If you can't modify the Security Manager, then you can't write to the file-system. – Elliott Frisch Feb 06 '15 at 00:46
  • Thanks. But once I have done that, how do I use Java to grab the right file path for where to write to? – Matt Boyle Feb 06 '15 at 00:47
  • What error do you get? Why do you think your current code is wrong? Oh, and your current system will break for large numbers of users (where large numbers is anything greater than 1). – Elliott Frisch Feb 06 '15 at 00:48
  • I don't have complete control with my code and can only write to user home which isn't ideal. Ideally I'd be able to write anywhere by specifying a path. The question listed seems to use getServlet but I don't have access to that. – Matt Boyle Feb 06 '15 at 00:50
  • Nor do you need access to that. Your current code gets the user's home directory (on a server or on a local system) and writes the file there. Of course, you probably don't have permission on the server to write to the file system (as I already told you). This is why it's such a terrible idea to write to a File. – Elliott Frisch Feb 06 '15 at 00:52
  • I own the server so can give myself access rights. Is there any resources you reccomend on doing this stuff right? – Matt Boyle Feb 06 '15 at 00:53
  • I've already told you twice, [*stream*](http://stackoverflow.com/questions/10875649/how-to-write-strings-to-an-outputstream) it. – Elliott Frisch Feb 06 '15 at 00:54
  • I really don't think that can work. I download a map segment to the server, run a Java program to do search on it then present the results. So would I download the map data as a stream to my Java program, do the search and then present that as a stream again? – Matt Boyle Feb 06 '15 at 00:57
  • Use a [`ByteArrayOutputStream`](http://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html) which is entirely in memory. You can then use [`toByteArray()`](http://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html#toByteArray%28%29) to get the value (again, from memory). – Elliott Frisch Feb 06 '15 at 00:59
  • Thanks for the advice. Will do some research into it. – Matt Boyle Feb 06 '15 at 00:59
  • Just a quick note on your inability to access the ServletRequest object in your application. Though you havent mentioned explicitly, it does look like you are using a jersey based rest service. This post - http://stackoverflow.com/questions/1043346/access-request-object-from-rest shows different ways to access the request object – ramp Feb 06 '15 at 02:15

0 Answers0