【问题标题】:Spring Rest HelloWorld app with Gradle without SpringBootSpring Rest HelloWorld 应用程序与 Gradle 没有 SpringBoot
【发布时间】:2018-03-07 14:53:34
【问题描述】:

如何在不使用 Spring Boot 的情况下使我的 Spring Rest HelloWorld 应用程序正常工作?

在 Eclipse 中的 tomcat 8.5 中运行此项目时,我希望 url “localhost:8080/hello”显示“HelloWorld”,但它显示的是 404

src/main/java/com.package/HelloController.java

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String helloWorld() {
        return "Hello World";
    }

}

src/main/java/com.package/HelloConfig.java

public class HelloConfig {

    @Bean
    public HelloController helloController() {
        return new HelloController();
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(HelloConfig.class);
        context.getBean(HelloController.class);
    }
}

build.gradle

plugins {
    id 'java'
    id 'war'
    id 'eclipse-wtp'
}

dependencies {
    compile 'org.springframework:spring-context:5.0.3.RELEASE'
    compile 'org.springframework:spring-web:5.0.3.RELEASE'
    testCompile 'junit:junit:4.12'
}

repositories {
    mavenCentral()
}

【问题讨论】:

  • 其余配置如何?您如何部署应用程序?
  • 您是否将控制器配置为 bean 或设置组件扫描?
  • 您可能在 url 中有一些额外的上下文。试试localhost:8080/<name of your war file>/hello

标签: java spring rest tomcat


【解决方案1】:

您可能需要在启动时使用 WebApplicationInitializer 和 AnnotationConfigWebApplicationContext。在 onStartup 方法中您可以提及应用程序的根上下文并访问其上的控制器映射。

public class CustomWebAppInitializer implements WebApplicationInitializer {

 @Override
 public void onStartup(ServletContext container) {
  AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
  rootContext.register(RootConfiguration.class);
  ContextLoaderListener contextLoaderListener = new ContextLoaderListener(rootContext);
  container.addListener(contextLoaderListener);

  AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
  webContext.register(MvcConfiguration.class);
  DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
  ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", dispatcherServlet);
  dispatcher.addMapping("/");
 }
}

【讨论】:

    【解决方案2】:

    我不确定您是否检查了 web.xml 的 web 应用程序并且您已正确设置以下配置

    <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:pathToYourSpringBeanConfig/channel-application-context.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>
        <!-- needed for ContextLoaderListener -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath: pathToYourSpringBeanConfig/channel-application-context.xml</param-value>
        </context-param>
    
        <!-- Bootstraps the root web application context before servlet initialization -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    

    您还需要提供您的上下文 xml 应用程序的位置,您需要在其中告诉您的上下文,如以下详细信息:

    <mvc:annotation-driven></mvc:annotation-driven>
        <context:component-scan base-package="group.*"></context:component-scan>
    

    PS : 如果你想访问没有战争名称的 URL,你可能想检查一下 Deploy war on Tomcat without the war name in the URL

    【讨论】:

    • 如果我的应用设置了一个配置类(使用@Bean 注释)而不是 xml,那么设置是什么?
    • 在休息控制器中你可以使用这个注解@EnableWebMvc@ComponentScan 如果你想摆脱xml应用程序上下文和web.xml配置那么请参考这个[docs.spring.io/spring/docs/3.1.x/javadoc-api/org/…]我会自己试一试,让你知道结果。
    【解决方案3】:

    回答我自己的问题:缺少的部分是 DispatcherServlet,负责将 http 请求委托给控制器的逻辑,例如我的示例中的 HelloController。

    基于 Spring 文档 (https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-servlet),有 3 种方式来配置 DispatcherServlet:

    1. 在 web.xml 中
    2. 覆盖 WebApplicationInitializer
    3. 扩展 AbstractAnnotationConfigDispatcherServletInitializer(推荐用于像我这样具有基于 Java 的配置的应用)

    src/main/java/com.package/ServletInitializer:

    public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return null;
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[] { HelloConfig.class };
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[] { "/" };
        }
    }
    

    注意:为什么投反对票?

    【讨论】:

      猜你喜欢
      • 2017-12-03
      • 2017-07-30
      • 2016-09-17
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 2022-06-21
      • 2020-10-04
      相关资源
      最近更新 更多