Spring MVC XML-less 配置异常:需要 ServletContext 来配置默认的 servlet 处理
Spring MVC XML-less configuration exception : A ServletContext is required to configure default servlet handling
我是 Spring 框架的新手,正在尝试 Spring MVC xml-less(没有 web.xml 或 mvc-dispatcher-servlet.xml) 配置,因为这是项目所需的。
当我尝试 运行 它时出现以下错误(使用 Jetty Local,再次是项目要求)
以下是我用于替换 web.xml:
的配置
(也试过扩展 AbstractAnnotationConfigDispatcherServletInitializer
但运气不好)
public class WebConfig implements WebApplicationInitializer {
@Override
public void onStartup( ServletContext servletContext ) throws ServletException {
WebApplicationContext rootContext = getContext(servletContext);
servletContext.addListener(new ContextLoaderListener(rootContext));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("mvc", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
private AnnotationConfigWebApplicationContext getContext(ServletContext ctx) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
//Tried various combination of un/commenting following options.
context.register( MvcServletConfig.class );
//context.setConfigLocation("com.xyz.myapp.configuration");
context.setServletContext( ctx );
//context.refresh();
//context.scan( "com.xyz.someapp.*" );
return context;
}
}
这是我的 MVC/Servlet 配置替换 mvc-dispatcher-servlet.xml:
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"com.xyz.myapp"})
public class MvcServletConfig extends WebMvcConfigurerAdapter {
public MvcServletConfig() { super(); }
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/login.jsp");
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/pages/");
bean.setSuffix(".jsp");
return bean;
}
}
这是我的 AppConfig:
@Configuration
@ComponentScan(basePackages = {"com.xyz.myapp.*"})
@Import( { HibernateConfig.class } )
public class AppConfig {}
这是我的 HibernateConfig,其中我有一个访问上下文的静态方法:
@Configuration
@EnableTransactionManagement
@ComponentScan( {"com.obsm.visensia.configuration"} )
@PropertySources( value ={@PropertySource("classpath:/application.properties")} )
public class HibernateConfig {
@Transactional
public static void InitialiseDummyData()
{
AbstractApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class);
AccountService accountService = (AccountService) context.getBean("accountService");
if ( accountService != null )
{
Role admin = new AdminRole();
Role serverAdmin = new ServerAdminRole();
Role normal = new NormalRole();
User adminUser = new User();
adminUser.setFirstName( "Kunal" );
adminUser.setLastName( "Patel" );
adminUser.setSex( Sex.Male );
adminUser.setUsername( "kp" );
adminUser.setPassword( "kp" );
adminUser.addRole( admin );
accountService.addUser( adminUser );
User serverAdminUser = new User();
serverAdminUser.setFirstName( "Server" );
serverAdminUser.setLastName( "Admin" );
serverAdminUser.setSex( Sex.Male );
serverAdminUser.setUsername( "serveradmin" );
serverAdminUser.setPassword( "serveradmin" );
serverAdminUser.addRole( serverAdmin );
accountService.addUser( serverAdminUser );
User normalUser = new User();
normalUser.setFirstName( "Normal" );
normalUser.setLastName( "User" );
normalUser.setSex( Sex.Undefined );
normalUser.setUsername( "normal" );
normalUser.setPassword( "normal" );
normalUser.addRole( normal );
accountService.addUser( normalUser );
context.close();
}
}
@Autowired
private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource( dataSource() );
sessionFactory.setPackagesToScan( new String[] { "com.obsm.visensia.model" } );
sessionFactory.setHibernateProperties( hibernateProperties() );
return sessionFactory;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName( environment.getRequiredProperty( "jdbc.driverClassName" ) );
dataSource.setUrl( environment.getRequiredProperty( "jdbc.url" ) );
dataSource.setUsername( environment.getRequiredProperty( "jdbc.username" ) );
dataSource.setPassword( environment.getRequiredProperty( "jdbc.password" ) );
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put( "hibernate.dialect", environment.getRequiredProperty( "hibernate.dialect" ) );
properties.put( "hibernate.show_sql", environment.getRequiredProperty( "hibernate.show_sql" ) );
properties.put( "hibernate.hbm2ddl.auto", environment.getRequiredProperty( "hibernate.hbm2ddl.auto" ) );
properties.put( "hibernate.format_sql", environment.getRequiredProperty( "hibernate.format_sql" ) );
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager ( SessionFactory sessFact )
{
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory( sessFact );
return transactionManager;
}
}
我的登录控制器:
@Controller
@RequestMapping("/")
public class LoginController {
@Autowired
private AccountService accountService;
@RequestMapping(method = RequestMethod.GET)
public String login(ModelMap model) {
HibernateConfig.InitialiseDummyData();
model.addAttribute( "user", new User() );
return "login";
}
@RequestMapping(method = RequestMethod.POST)
public String verifyUser(@ModelAttribute("user") User user, Model model)
{
if ( accountService.verifyUser( user.getUsername(), user.getPassword() ) ) {
User usr = accountService.findUserByUsername( user.getUsername() );
model.addAttribute( "message", "Welcome, " + usr.getFirstName() );
return "hello";
}
else
return "login";
}
}
我的 HelloController:
@Controller
@RequestMapping("/")//Doesn't work even if I change it to '/hello'
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
model.addAttribute("message", "Hello world!");
return "hello";
}
}
请帮忙,我已经在这里卡了 3 天了:'(
更新
Jetty 9.2.4v20141103,这是堆栈跟踪:
Jetty 9.2.4v20141103 and following is the stacktrace:
`java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:416)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$b833a897.CGLIB$defaultServletHandlerMapping(<generated>)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$b833a897$$FastClassBySpringCGLIB$ff08f3.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$b833a897.defaultServletHandlerMapping(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1113)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1008)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:505)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at com.obsm.visensia.configuration.HibernateConfig.InitialiseDummyData(HibernateConfig.java:32)
at com.obsm.visensia.controller.LoginController.login(LoginController.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
at org.eclipse.jetty.io.AbstractConnection.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:540)
at java.lang.Thread.run(Thread.java:722)`
添加了 class 以在我的上下文刷新后立即初始化我的数据库,如下所示:
@Component
public class DbInitialiserOnStartUp implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private AccountService accountService;
@Transactional
@Override
public void onApplicationEvent( ContextRefreshedEvent contextRefreshedEvent ) {
if ( accountService != null )
{
//inserts etc...
}
}
}
我测试了它,它工作正常...试试这个:
// You named it WebConfig
public class WebAppInitializer implements WebApplicationInitializer { // web.xml replacement
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
// Here you need to change "io.shido.config" to your config location
applicationContext.setConfigLocation("io.shido.config");
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher",
new DispatcherServlet(applicationContext)); // Register and map the dispatcher servlet
//servletContext.setInitParameter("spring.profiles.default", "development");
servletContext.addListener(new ContextLoaderListener(applicationContext));
//applicationContext.register(AppConfig.class); // Manage the lifecycle of the root application context
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/web/*"); // ...and here also change the context
}
}
请注意,我也在使用 /web
作为我的上下文...因此请相应地更改它。有示例项目 here in case you want to take a look; and this 是 ZeroTurnaround 家伙写的关于该主题的非常非常好的文章。
此外,我的 Maven POM 文件中有:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<!--<packagingExcludes>WEB-INF/web.xml</packagingExcludes>-->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
更新
您的 Spring 配置工作正常(但您确实可以进一步改进它);当您呼叫 HibernateConfig.InitialiseDummyData();
时,问题出在 LoginController
线上。评论那一行,一切都会好起来的。
调用该方法时,您正在启动另一个 Spring 上下文。我无法修复数据库的问题,因为我没有您的架构...在进行 概念验证 时最好使用内存数据库。尝试 improve/fix 那段代码,你应该可以开始了。
import javax.servlet.MultipartConfigElement;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { WebConfig2.class };
}
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] { "/" };
}
}
我是 Spring 框架的新手,正在尝试 Spring MVC xml-less(没有 web.xml 或 mvc-dispatcher-servlet.xml) 配置,因为这是项目所需的。
当我尝试 运行 它时出现以下错误(使用 Jetty Local,再次是项目要求)
以下是我用于替换 web.xml:
的配置(也试过扩展 AbstractAnnotationConfigDispatcherServletInitializer
但运气不好)
public class WebConfig implements WebApplicationInitializer {
@Override
public void onStartup( ServletContext servletContext ) throws ServletException {
WebApplicationContext rootContext = getContext(servletContext);
servletContext.addListener(new ContextLoaderListener(rootContext));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("mvc", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
private AnnotationConfigWebApplicationContext getContext(ServletContext ctx) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
//Tried various combination of un/commenting following options.
context.register( MvcServletConfig.class );
//context.setConfigLocation("com.xyz.myapp.configuration");
context.setServletContext( ctx );
//context.refresh();
//context.scan( "com.xyz.someapp.*" );
return context;
}
}
这是我的 MVC/Servlet 配置替换 mvc-dispatcher-servlet.xml:
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"com.xyz.myapp"})
public class MvcServletConfig extends WebMvcConfigurerAdapter {
public MvcServletConfig() { super(); }
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/login.jsp");
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/pages/");
bean.setSuffix(".jsp");
return bean;
}
}
这是我的 AppConfig:
@Configuration
@ComponentScan(basePackages = {"com.xyz.myapp.*"})
@Import( { HibernateConfig.class } )
public class AppConfig {}
这是我的 HibernateConfig,其中我有一个访问上下文的静态方法:
@Configuration
@EnableTransactionManagement
@ComponentScan( {"com.obsm.visensia.configuration"} )
@PropertySources( value ={@PropertySource("classpath:/application.properties")} )
public class HibernateConfig {
@Transactional
public static void InitialiseDummyData()
{
AbstractApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class);
AccountService accountService = (AccountService) context.getBean("accountService");
if ( accountService != null )
{
Role admin = new AdminRole();
Role serverAdmin = new ServerAdminRole();
Role normal = new NormalRole();
User adminUser = new User();
adminUser.setFirstName( "Kunal" );
adminUser.setLastName( "Patel" );
adminUser.setSex( Sex.Male );
adminUser.setUsername( "kp" );
adminUser.setPassword( "kp" );
adminUser.addRole( admin );
accountService.addUser( adminUser );
User serverAdminUser = new User();
serverAdminUser.setFirstName( "Server" );
serverAdminUser.setLastName( "Admin" );
serverAdminUser.setSex( Sex.Male );
serverAdminUser.setUsername( "serveradmin" );
serverAdminUser.setPassword( "serveradmin" );
serverAdminUser.addRole( serverAdmin );
accountService.addUser( serverAdminUser );
User normalUser = new User();
normalUser.setFirstName( "Normal" );
normalUser.setLastName( "User" );
normalUser.setSex( Sex.Undefined );
normalUser.setUsername( "normal" );
normalUser.setPassword( "normal" );
normalUser.addRole( normal );
accountService.addUser( normalUser );
context.close();
}
}
@Autowired
private Environment environment;
@Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource( dataSource() );
sessionFactory.setPackagesToScan( new String[] { "com.obsm.visensia.model" } );
sessionFactory.setHibernateProperties( hibernateProperties() );
return sessionFactory;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName( environment.getRequiredProperty( "jdbc.driverClassName" ) );
dataSource.setUrl( environment.getRequiredProperty( "jdbc.url" ) );
dataSource.setUsername( environment.getRequiredProperty( "jdbc.username" ) );
dataSource.setPassword( environment.getRequiredProperty( "jdbc.password" ) );
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put( "hibernate.dialect", environment.getRequiredProperty( "hibernate.dialect" ) );
properties.put( "hibernate.show_sql", environment.getRequiredProperty( "hibernate.show_sql" ) );
properties.put( "hibernate.hbm2ddl.auto", environment.getRequiredProperty( "hibernate.hbm2ddl.auto" ) );
properties.put( "hibernate.format_sql", environment.getRequiredProperty( "hibernate.format_sql" ) );
return properties;
}
@Bean
@Autowired
public HibernateTransactionManager transactionManager ( SessionFactory sessFact )
{
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory( sessFact );
return transactionManager;
}
}
我的登录控制器:
@Controller
@RequestMapping("/")
public class LoginController {
@Autowired
private AccountService accountService;
@RequestMapping(method = RequestMethod.GET)
public String login(ModelMap model) {
HibernateConfig.InitialiseDummyData();
model.addAttribute( "user", new User() );
return "login";
}
@RequestMapping(method = RequestMethod.POST)
public String verifyUser(@ModelAttribute("user") User user, Model model)
{
if ( accountService.verifyUser( user.getUsername(), user.getPassword() ) ) {
User usr = accountService.findUserByUsername( user.getUsername() );
model.addAttribute( "message", "Welcome, " + usr.getFirstName() );
return "hello";
}
else
return "login";
}
}
我的 HelloController:
@Controller
@RequestMapping("/")//Doesn't work even if I change it to '/hello'
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printWelcome(ModelMap model) {
model.addAttribute("message", "Hello world!");
return "hello";
}
}
请帮忙,我已经在这里卡了 3 天了:'(
更新
Jetty 9.2.4v20141103,这是堆栈跟踪:
Jetty 9.2.4v20141103 and following is the stacktrace:
`java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:416)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$b833a897.CGLIB$defaultServletHandlerMapping(<generated>)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$b833a897$$FastClassBySpringCGLIB$ff08f3.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$b833a897.defaultServletHandlerMapping(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1113)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1008)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:505)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at com.obsm.visensia.configuration.HibernateConfig.InitialiseDummyData(HibernateConfig.java:32)
at com.obsm.visensia.controller.LoginController.login(LoginController.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
at org.eclipse.jetty.io.AbstractConnection.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:540)
at java.lang.Thread.run(Thread.java:722)`
添加了 class 以在我的上下文刷新后立即初始化我的数据库,如下所示:
@Component
public class DbInitialiserOnStartUp implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private AccountService accountService;
@Transactional
@Override
public void onApplicationEvent( ContextRefreshedEvent contextRefreshedEvent ) {
if ( accountService != null )
{
//inserts etc...
}
}
}
我测试了它,它工作正常...试试这个:
// You named it WebConfig
public class WebAppInitializer implements WebApplicationInitializer { // web.xml replacement
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
// Here you need to change "io.shido.config" to your config location
applicationContext.setConfigLocation("io.shido.config");
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher",
new DispatcherServlet(applicationContext)); // Register and map the dispatcher servlet
//servletContext.setInitParameter("spring.profiles.default", "development");
servletContext.addListener(new ContextLoaderListener(applicationContext));
//applicationContext.register(AppConfig.class); // Manage the lifecycle of the root application context
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/web/*"); // ...and here also change the context
}
}
请注意,我也在使用 /web
作为我的上下文...因此请相应地更改它。有示例项目 here in case you want to take a look; and this 是 ZeroTurnaround 家伙写的关于该主题的非常非常好的文章。
此外,我的 Maven POM 文件中有:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<!--<packagingExcludes>WEB-INF/web.xml</packagingExcludes>-->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
更新
您的 Spring 配置工作正常(但您确实可以进一步改进它);当您呼叫 HibernateConfig.InitialiseDummyData();
时,问题出在 LoginController
线上。评论那一行,一切都会好起来的。
调用该方法时,您正在启动另一个 Spring 上下文。我无法修复数据库的问题,因为我没有您的架构...在进行 概念验证 时最好使用内存数据库。尝试 improve/fix 那段代码,你应该可以开始了。
import javax.servlet.MultipartConfigElement;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { WebConfig2.class };
}
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] { "/" };
}
}