简体   繁体   中英

Java Servlet: PrintWriter strange behaviour with variable

I'm learning how to program servlet by following these 1 2 official tutorials. I cannot find a solution to a simple question about the strange behaviour of PrintWriter class with variables. The code is the following:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ServletExample extends HttpServlet {

   public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws IOException, ServletException
   {
    response.setContentType("text/html");       
    PrintWriter out = response.getWriter();
    out.println("<html>");
    out.println("<head>");  
    out.println("<title>First example</title>");
    out.println("</head>");
    out.println("<h2>System information</h2>");
    out.println("Host name: " + request.getRemoteHost() + "<br>");
    out.println("Remote address: " + request.getRemoteAddr() + "<br>");
    out.println("Port: " + request.getServerPort() + "<br>");
    out.println("Encoding: " + request.getCharacterEncoding() + "<br>");
    out.println("Method: " + request.getMethod() + "<br>");
    out.println("Protocol: " + request.getProtocol() + "<br>");
    out.println("Address: " + request.getRequestURI() + "<br>");
    out.println("Path: " + request.getPathInfo() + "<br>");
    out.println("</body>");
    out.println("</html>");
    out.close();
    }
}

The output of the servlet on servlet container is displayed up to

out.println("<h2>System information</h2>");

I cannot figure out why, but I discovered that by splitting the following line into these lines works:

out.println("Host name: ");
out.println(request.getRemoteHost())
out.println("<br>");

I searched a lot on the Web, but I cannot find and answer.

I'm under ubuntu mate 16.04 LTS with apache tomcat 8 installed from repository.

Edit I further investigate about such behaviour by trying different tomcat 7 under ubuntu mate 16.04 LTS and different OS windows 10 with xampp and tomcat 7. The result is the same.

So I took the Request Info official example present into examples folder installed together with tomcat. The code of the example is this:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class RequestInfo extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");
    out.println("<head>");
    out.println("<title>Request Information Example</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h3>Request Information Example</h3>");
    out.println("Method: " + request.getMethod());
    out.println("Request URI: " + request.getRequestURI());
    out.println("Protocol: " + request.getProtocol());
    out.println("PathInfo: " + request.getPathInfo());
    out.println("Remote Address: " + request.getRemoteAddr());
    out.println("</body>");
    out.println("</html>");
}

/**
 * We are going to perform the same operations for POST requests
 * as for GET methods, so this method just sends the request to
 * the doGet method.
 */

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
    doGet(request, response);
}
}

As expected it does not work and its behaviour it is the same of the previous code. However, if I open prebuilt version inside the example folder it works.

Finally, by splitting each line into several lines it works as described before. It is really strange behaviour.

I would recommend that you use a StringBuilder object to generate the result, then. You can, if desired, calculate the content length, which is useful in some situations.

StringBuilder sbText = new StringBuilder();
sbText.append("<html>")
    .append("<head>")
    .append(etc...);

String text = sbText.toString();
// Option A:
response.getWriter().print(text);

// Option B:
byte[] bytes = text.getBytes();
response.setContentLength(bytes.length);
response.getOutputStream().write(bytes);

I found the solution at my strange problem. I tried also with latest tomcat v9.0.8 that uses jvm v1.8.0_171-b11 while I compiled my code with javac 1.9. By using javac v1.8 it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM