Why am I getting "java.net.MalformedURLException: no protocol:" when I post form to a servlet?

StackOverflow https://stackoverflow.com/questions/21468776

  •  05-10-2022
  •  | 
  •  

Pregunta

Good day, in my simple test webapp project I have this Test.jsp file:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test page</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/testCaptureParts" method="post">
        <textarea id="inputxml" name="inputxml" rows="20" cols="80"></textarea>
        <input type="submit" value="submit" />
    </form>
</body>
</html>

It generates this HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test page</title>
</head>
<body>
    <form action="/TestApp/testCaptureParts" method="post">
        <textarea id="inputxml" name="inputxml" rows="20" cols="80"></textarea>
        <input type="submit" value="submit" />
    </form>
</body>
</html>

The /TestApp/testCaptureParts is a servlet that implements doPost() method.

When I submit the form, I'm getting following exception even before servlets's doPost() method is called:

I 30, 2014 11:05:36 ODP. org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [TestCapturePartsServlet] in context with path
[/TestApp] threw exception
java.net.MalformedURLException: no protocol: captureParts
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at cz.test.servlet.TestCapturePartsServlet.doPost(TestCapturePartsServlet.java:47)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

I tried to hardcode the URL as:

http://127.0.0.1/TestApp/testCaptureParts 

But then when I submit the form in Mozilla it opens the "SaveAs" dialog saying "You opened testCaptureParts. It's application/octet-stream. What do you want to do?". If I submit it Internet Explorer it opens a blank page with some unreadable characters.

á`Fžű^Čůňţđba`°ÁÍÖKâ×­C´
Á6đMäϬ?ye(lЧĄŻÂ
ÉfDĺŇ›Áţל]ęÓhą–ŹôŐ
@±.GLMC©°ľf`qpP

Please advise, how can I post the form to a servlet for further processing? Thank you in advance.

EDIT - This is the servlet class:

public class TestCapturePartsServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
        doPost(httpRequest, httpResponse);
    }

    @Override
    protected void doPost(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException  {
        String inputxml = httpRequest.getParameter("inputxml");
        httpResponse.setContentType("text/plain"); 
        PrintWriter out = httpResponse.getWriter();
        try {
           String s = "Servlet response.";
           out.println(s);
           out.println("Parameter value = " + inputxml);
        } finally {
           out.close();
        }
    }
}
  1. When I open URL in the browser as a GET request I'm getting expected text response.
  2. When I POST the form from the browser to the URL I'm getting the "application/octet-stream" stuff.
  3. When I POST some data from the RESTClient to the URL I'm getting expected text response.

I switched to the debugging mode and I set the breakpoint on the first line of the doPost() method. The execution stops for points 1 and 3 on the breakpoint. But for point 2 it doesn't, it looks like doPost() method is not called at all.

¿Fue útil?

Solución

Two things:

  1. Unless you want to do special stuff with the servlet's output, using a Writer is a lot easier.
  2. You're not announcing an output type via setContentType, so the browser has to make a wild guess concerning the nature of the data you're throwing at it.

At its simplest, and using the recommendations above, your method could look like this

public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException
{
    // read the parameter that got passed
    String inputxml = request.getParameter("inputxml");
    response.setContentType("text/plain"); 
    PrintWriter out = response.getWriter();
    try {
       String s = "Servlet response";
       out.println(s);
       out.println("parameter value = " + inputxml);
    } finally {
       out.close();
    }
}

Note: a servlet can use either the OutputStream or the PrintWriter, not both.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top