Как настроить Spring MVC с чистой конфигурацией на основе Java?
У меня есть то, что я считаю довольно простой установкой MVC Spring. Мое applicationContext.xml следующее:
<mvc:annotation-driven />
<mvc:resources mapping="/css/**" location="/css/" />
<context:property-placeholder location="classpath:controller-test.properties" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/" p:suffix=".jsp" />
Мой web.xml в настоящее время:
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Я пытаюсь преобразовать этот набор в чистую конфигурацию на основе Java. Я искал в Интернете и до сих пор, я придумал материал, который объясняет (что-то), как сделать конфигурацию Java, но не объясняет, как зарегистрировать эту конфигурацию Java с помощью среды, то есть веб-контекста.
Что я до сих пор в терминах @Configuration:
@Configuration
@EnableWebMvc
@PropertySource("classpath:controller.properties")
@ComponentScan("com.project.web")
public class WebSpringConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
}
@Bean
public ViewResolver configureViewResolver() {
InternalResourceViewResolver viewResolve = new InternalResourceViewResolver();
viewResolve.setPrefix("/WEB-INF/views/");
viewResolve.setSuffix(".jsp");
return viewResolve;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}
Как зарегистрировать это в веб-контейнере? Я использую последний Spring (4.02).
Спасибо!
Ответы
Ответ 1
Вам необходимо внести следующие изменения в web.xml
для поддержки конфигурации на основе Java. Это скажет DispatcherServlet
загрузить конфигурацию, используя основанную на аннотации конфигурацию Java AnnotationConfigWebApplicationContext
. Вам нужно только передать местоположение вашего конфигурационного файла Java параметру contextConfigLocation
, как показано ниже
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/*path to your WebSpringConfig*/ </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Обновление: сделать то же самое без внесения изменений в web.xml
Вы даже можете сделать это без web.xml
, поскольку Servlet Specification 3.0 делает web.xml
необязательным. Вам нужно только реализовать/настроить интерфейс WebApplicationInitializer
для настройки ServletContext
, который позволит вам создавать, настраивать и выполнять регистрацию DispatcherServlet
программным способом. Хорошо, что WebApplicationInitializer
обнаруживается автоматически.
Таким образом, нужно реализовать WebApplicationInitializer
, чтобы избавиться от web.xml
.
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(WebSpringConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(DispatcherConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
Обновление: из комментариев
Немного более запутанное объяснение также включено в официальную ссылку Spring Spring 4 Release
Ссылка:
http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html
Ответ 2
Конфигурация на основе Java без добавления каких-либо элементов в web.xml
. WebApplicationInitializer идеально подходит для использования с классами @Configuration
основе кода @Configuration
WebApplicationInitializer "Интерфейс, который будет реализован в Servlet 3.0+ environments
для программной настройки ServletContext - в отличие от (или, возможно, в сочетании) с традиционным подходом на основе web.xml. Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container
. Использование Servlet Spec 3.0 от Tomcat 7
Начиная с Spring 3.2, в списке был указан абстрактный класс, в котором реализован WebApplicationInitializer, который будет автоматически обнаруживаться SrevletContainer.
AbstractAnnotationConfigDispatcherServletInitializer extends
AbstractDispatcherServletInitializer extends
AbstractContextLoaderInitializer implements WebApplicationInitializer
Использование версии Spring 4.1.6.RELEASE
с модулями core, web, webmvc, beans
.
public class WebXML_DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { MvcServletXMLConfigurer.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
Конфигурация на основе Java для обслуживания статических ресурсов с помощью Spring. Весенний ботинок
@Configuration
@EnableWebMvc // <mvc:annotation-driven />
@ComponentScan(value = {"com.github.yash777.controllers"})
// <context:component-scan base-package="com.github.yash777" />
public class MvcServletXMLConfigurer extends WebMvcConfigurerAdapter implements WebMvcConfigurer {
/**
* <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
* p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
*
* @return InternalResourceViewResolver as a bean configuration.
*/
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("WebMvcConfigurer - addResourceHandlers() function get loaded...");
// <mvc:resources mapping="/styles/**" location="/css/" />
registry
.addResourceHandler("/styles/**")
.addResourceLocations("/css/") // webapp/css/
.setCachePeriod(3600)
.resourceChain(true) // Spring 4.1
.addResolver(new GzipResourceResolver()) // Spring 4.1
.addResolver(new PathResourceResolver()); // Spring 4.1
// <mvc:resources mapping="/static/**" location="/static/" />
registry.addResourceHandler("/static/**")
.addResourceLocations("/static/", "classpath:/static/") // src/main/resources/static/
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
}
Перечислил пример контроллера:
@Controller
@RequestMapping(value = { "/controller", "/c" })
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;
@RequestMapping(value = {"/message", "/m"}, method = RequestMethod.GET )
public void message(HttpServletRequest request, HttpServletResponse response ) throws IOException {
System.out.println("@Controller Get method called.");
}
@RequestMapping(value = "/getView", method = RequestMethod.GET )
public ModelAndView setViewName( Model model ) {
System.out.println("GET... /getView");
ModelAndView mav = new ModelAndView();
mav.setViewName("test");
return mav;
}
}
WEB-INF/web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>