0

I implementing own tiny web server using sun.net.HttpServer... to enable css and javascript i wrote code using HttpHandler, but js directory having two files...it's working for one file, but when two files to transfer... error occurred. like

java.io.IOException: headers already sent

How to fix this... here is coding

class DirectoryServicesForJS implements HttpHandler {

    @Override
    public void handle(HttpExchange http) throws IOException {
        // HTTP METHOD (GET, POST, DELETE, PUT)
        System.out.println("Java script transfered...");
        List<String> jsFiles = new ArrayList<String>();
        ;
        Files.walk(Paths.get("web/js")).forEach(filePath -> {
            if (Files.isRegularFile(filePath)) {
                jsFiles.add(filePath.toString());
            }
        });
        for (String filePath : jsFiles) {
            try {
                StringBuilder code = new StringBuilder();
                try {
                    BufferedReader in = new BufferedReader(new FileReader(
                            filePath));
                    String str;
                    while ((str = in.readLine()) != null) {
                        code.append(str);
                    }
                    in.close();

                } catch (IOException e) {
                    System.out.println();
                }
                String response = code.toString();
                http.sendResponseHeaders(200, response.length()); // error line
                System.out.println(filePath);
                http.setAttribute("Content-Type", "text/javascript");
                OutputStream os = http.getResponseBody();
                os.write(response.getBytes());
                os.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}
Kernel
  • 165
  • 4
  • 14
  • 1
    You seem to be trying to send several files for a single request. HTTP doesn't work that way. If the client requests for `/index.html`, you send the contents of that file and nothing else. Remove your for-loop, it won't work. – Kayaman Mar 05 '15 at 09:21
  • Ok bro. If i changed like this... `List jsFiles = new ArrayList(); Files.walk(Paths.get("web/js")).forEach(filePath -> { if (Files.isRegularFile(filePath)) { jsFiles.add(filePath.getFileName().toString()); } }); for (String jsFile : jsFiles) { System.out.println(jsFile); server.createContext("/js/"+jsFile, new DirectoryServicesForJS(jsFile)); }` that also called only once... what should I do? to fix and get solutions. – Kernel Mar 05 '15 at 09:51
  • Where should I apply multi-threading here, either HttpHandler or HttpServer? – Kernel Mar 05 '15 at 09:55
  • You need to answer with a single file for a single request. Your code doesn't even care about which file the request was for (or whether it was even a `GET` request). Examine the `HttpExchange` to see what was requested, then return that file. – Kayaman Mar 05 '15 at 10:06
  • even multithreading not working... `for (String jsFile : jsFiles) { System.out.println(jsFile); new Thread(new Runnable() { public void run() { server.createContext("/js/"+jsFile, new DirectoryServicesForJS(jsFile)); } }).start(); }` What should I do? how to get solutions... reply me @Kayaman – Kernel Mar 05 '15 at 10:12
  • I told you what to do. Multithreading has nothing to do with this. – Kayaman Mar 05 '15 at 10:14

1 Answers1

0

to transfer all css and js, we can code write like this...

        server = HttpServer.create(new InetSocketAddress(port), backlog);
        server.createContext("/", new IndexPage());
        List<String> cssFiles = new ArrayList<String>();
        Files.walk(Paths.get("web/css")).forEach(filePath -> {
            if (Files.isRegularFile(filePath)) {
                cssFiles.add(filePath.getFileName().toString());
            }
        });
        for (String cssFile : cssFiles) {
            server.createContext("/css/" + cssFile,
                    new DirectoryServicesForCSS(cssFile));
        }
        List<String> jsFiles = new ArrayList<String>();
        Files.walk(Paths.get("web/js")).forEach(filePath -> {
            if (Files.isRegularFile(filePath)) {
                jsFiles.add(filePath.getFileName().toString());
            }
        });
        for (String jsFile : jsFiles) {
            server.createContext("/js/" + jsFile,
                    new DirectoryServicesForJS(jsFile));
        }
        // server.setExecutor(Executors.newCachedThreadPool());
        server.setExecutor(null);
        server.start();

and we should write HttpHandler code like this...

    class DirectoryServicesForCSS implements HttpHandler {

    private String style;

    public DirectoryServicesForCSS(String style) {
        this.style = style;
    }

    @Override
    public void handle(HttpExchange http) throws IOException {
        // HTTP METHOD (GET, POST, DELETE, PUT)
        if (http.getRequestMethod().equals("GET")) {
            System.out.println("cascade style sheet transfered..." + style);
            try {
                StringBuilder contentBuilder = new StringBuilder();
                try {
                    BufferedReader in = new BufferedReader(new FileReader(
                            "web/css/" + style));
                    String str;
                    while ((str = in.readLine()) != null) {
                        contentBuilder.append(str);
                    }
                    in.close();
                } catch (IOException e) {
                }
                String response = contentBuilder.toString();
                http.sendResponseHeaders(200, response.length());
                OutputStream os = http.getResponseBody();
                os.write(response.getBytes());
                os.flush();
                os.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

     class DirectoryServicesForJS implements HttpHandler {

    private String script;

    public DirectoryServicesForJS(String script) {
        this.script = script;
    }

    @Override
    public void handle(HttpExchange http) throws IOException {
        // HTTP METHOD (GET, POST, DELETE, PUT)
        if (http.getRequestMethod().equals("GET")) {
            System.out.println("Java scripts transfered..." + script);
            try {

                StringBuilder code = new StringBuilder();
                try {
                    BufferedReader in = new BufferedReader(new FileReader(
                            "web/js/" + script));
                    String str;
                    while ((str = in.readLine()) != null) {
                        code.append(str);
                    }
                    in.close();

                } catch (IOException e) {
                    System.out.println();
                }
                String response = code.toString();
                http.sendResponseHeaders(200, response.length());
                http.setAttribute("Content-Type", "text/javascript");
                OutputStream os = http.getResponseBody();
                os.write(response.getBytes());
                os.flush();
                os.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

and make sure that its available in our html page for example..

<html>
<head>
    <title>Shopping Portal</title>
    <link href="css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body class="container-fluid">
<div class="alert alert-success alert-dismissable">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
    <strong>Successfully!</strong> You are new user.
</div>
    <h1 class="text-primary">Welcome to Shopping Portal</h1>
    <hr/>
    <p>Content will be updated later</p>
</body>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</html>
Kernel
  • 165
  • 4
  • 14