Одна из интересных проблем, которые я обнаружил, заключается в том, что я часто хочу, чтобы мой сервлет был бином, управляемым Spring. Таким образом, он может выполнять все внедрение зависимостей и т. Д. Но обычно вы должны указывать свои сервлеты в web.xml, и это означает, что ваш контейнер (например, Tomcat), а не Spring, создаст сервлет.
Существует способ обойти это, используя HttpRequestHandlerServlet . Мой файл web.xml содержит следующие строки:
<servlet>
<servlet-name>dataProvider</servlet-name>
<servlet-class>
org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>documentCreator</servlet-name>
<servlet-class>
org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dataProvider</servlet-name>
<url-pattern>/dataProvider/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>documentCreator</servlet-name>
<url-pattern>/documentCreator/*</url-pattern>
</servlet-mapping>
Это говорит Spring, что он собирается использовать два своих bean-компонента в качестве сервлетов, один называется dataProvider, а другой - documentCreator. Он должен будет определить, что это за компоненты, используя файл конфигурации xml или аннотации. Я предпочитаю аннотации, такие как @ Controller.
Так что же происходит, когда Tomcat получает запрос, например, GET / dataProvider / test
Из раздела отображения сервлетов он знает, что должен передать этот запрос первому созданному им HttpRequestHandlerServlet. Этот класс знает, что у него есть имя dataProvider, и он ищет в контексте Spring бин с именем dataProvider. Затем он вызывает метод handleRequest для этого компонента.
Мой класс DataProvider выглядит следующим образом:
@Controller
public class DataProvider extends HttpServlet implements HttpRequestHandler {
@Autowired
private OtherBeanType otherBean
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
// my doGet method
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
// my doPost method
}
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getMethod().equalsIgnoreCase("GET")) {
doGet(request, response);
} else if (request.getMethod().equalsIgnoreCase("POST")) {
doPost(request, response);
}
}
}
Я думаю, что немного жаль, что нам нужен этот метод handleRequest () (и если вы используете что-то кроме Get и Post, вам нужно будет добавить их туда). Было бы лучше, если бы HttpRequestHandlerServlet мог сделать эту работу за вас, но сейчас это так.