当我将表单发布到servlet时,为什么会出现“java.net.MalformedURLException:no protocol:”?

时间:2014-01-30 22:28:15

标签: java-ee servlet-3.0

美好的一天,在我的简单测试webapp项目中,我有这个Test.jsp文件:

<%@ 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>

它生成此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>

/ TestApp / testCaptureParts是一个实现doPost()方法的servlet。

当我提交表单时,即使在调用servlet的doPost()方法之前,我也会遇到异常:

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)

我尝试将网址硬编码为:

http://127.0.0.1/TestApp/testCaptureParts 

但是当我在Mozilla中提交表单时,它会打开“SaveAs”对话框,说“你打开了testCaptureParts。它是application / octet-stream。你想做什么?”。 如果我提交Internet Explorer,它会打开一个包含一些不可读字符的空白页面。

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

请告知,如何将表单发布到servlet以进行进一步处理?提前谢谢。

编辑 - 这是servlet类:

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. 当我在浏览器中打开URL作为GET请求时,我得到了预期的文本响应。
  2. 当我将表单从浏览器发布到URL时,我收到了“application / octet-stream”的内容。
  3. 当我将一些来自RESTClient的数据发布到URL时,我得到了预期的文本响应。
  4. 我切换到调试模式,并在doPost()方法的第一行设置断点。断点上的点1和3的执行停止。但是对于第2点它没有,看起来根本没有调用doPost()方法。

1 个答案:

答案 0 :(得分:0)

两件事:

  1. 除非你想用servlet的输出做特殊的事情,否则使用Writer要容易得多。
  2. 您没有通过setContentType宣布输出类型,因此浏览器必须对您投掷的数据的性质进行猜测。
  3. 最简单,使用上面的建议,您的方法可能如下所示

    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();
        }
    }
    

    注意:servlet可以使用OutputStream PrintWriter,而不是两者。