自定义Servlet中不支持POST作为Spring Boot中的@Bean

时间:2015-04-18 01:27:26

标签: java spring spring-mvc servlets spring-boot

我试图将第三方servlet集成到我的Spring Boot应用程序中,当我尝试向servlet提交POST时,我在日志中看到以下内容:

PageNotFound: Request method 'POST' not supported

我做了一个简单的测试来证明这一点。我开始使用auto generated Spring Boot project。然后我创建了以下Servlet:

public class TestServlet extends HttpServlet {
    private static final Logger log = LoggerFactory.getLogger(TestServlet.class);

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp); //To change body of generated methods, choose Tools | Templates.
        log.info("doPost was called!!");
    }

}

然后我创建了这样的配置:

@Configuration
public class ServletConfig {
    @Bean //exposes the TestServlet at /test
    public Servlet test() {
        return new TestServlet();
    }        
}

然后我在Tomcat7中运行该应用程序。我在日志中看到:

ServletRegistrationBean: Mapping servlet: 'test' to [/test/]

然后我尝试用cUrl命中端点,如下所示:

curl -v http://localhost:8080/test -data-binary '{"test":true}'

curl -XPOST -H'Content-type: application/json' http://localhost:8080/test -d '{"test":true}'

我已尝试添加@RequestMapping,但这也没有用。任何人都可以帮我弄清楚如何在我的Spring Boot应用程序中支持另一个Servlet吗?

您可以在此处找到示例应用程序:https://github.com/andrewserff/servlet-demo

谢谢!

2 个答案:

答案 0 :(得分:3)

根据我以前的经验,你必须在最后用斜杠调用servlet(比如http://localhost:8080/test/)。如果你没有把斜杠放在最后,请求将被路由到映射到/的servlet,默认情况下是Spring的DispatcherServlet(你的错误消息来自那个servlet)。

答案 1 :(得分:2)

TestServlet#doPost()实现调用super.doPost() - 始终发送40x错误(405400,具体取决于所使用的HTTP协议)。< / p>

以下是实施:

protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    String protocol = req.getProtocol();
    String msg = lStrings.getString("http.method_post_not_supported");
    if (protocol.endsWith("1.1")) {
        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
    } else {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
    }
}

可以使用两种方式注册Servlet: 将Servlet注册为Bean(您的方法 - 应该没问题)或 使用ServletRegistrationBean

@Configuration
public class ServletConfig {

    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
        return new ServletRegistrationBean(new TestServlet(), "/test/*");
    }
}

略有变化的Servlet:

public class TestServlet extends HttpServlet {
   private static final Logger log = LoggerFactory.getLogger(TestServlet.class);

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // super.doPost(req, resp);
        log.info("doPost was called!!");
    }
}