jetty集成Spring MVC

分享者
• 阅读 284

jetty作为一个轻量级的Servlet容器用来作为嵌入的Servlet服务器非常方便。通过Spring mvc 的相关文档的理解,试验了几种jetty 集成Spring Mvc的方法,进行记录。

1、通过web.xml方式配置集成

public class JettyServer {

    public static void main(String[] args) throws Exception {
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8091);
        server.setConnectors(new Connector[] { connector });

        String webappPath = Paths.get(JettyServer.class.getClassLoader().getResource(".").toURI()).toAbsolutePath().toString();
        WebAppContext context = new WebAppContext( webappPath,"/");

        server.setHandler(context);
        server.start();
        // 打印dump时的信息
        System.out.println(server.dump());
        // join当前线程
        server.join();
    }
}

web.xml的位置在:

 resources:
    WEB-INF:
        web.xml

配置文件的内容可以参考:

<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app-context-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

</web-app>

上面的代码,在创建WebAppContext的时候指定了具体webapp的路径为项目的起始目录(编译后运行的起始目录)。没有通过代码明确指定web.xml的位置,猜测javaEE规范规定了 Servlet容器自动的寻找webapp下WEB-INF目录下的web.xml进行加载。web.xml中指定了Spring Mvc 的配置。

2、通过jetty的设置配置DispatcherServlet

public class ManualJettyServer {


    private static String CONTEXT_PATH = "/";

    private static String MAPPING_URL  = "/*";

    public static void main(String[] args) throws Exception {
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8090);
        server.setConnectors(new Connector[] { connector });

        WebAppContext context = new WebAppContext();
        ServletContextHandler handler = servletContextHandler(webApplicationContext());

        server.setHandler(handler);
        // 启动
        server.start();
        // 打印dump时的信息
        System.out.println(server.dump());
        // join当前线程
        server.join();
    }

    private static ServletContextHandler servletContextHandler(WebApplicationContext context) {
        ServletContextHandler handler = new ServletContextHandler();
        handler.setContextPath(CONTEXT_PATH);
        handler.addServlet(new ServletHolder(new DispatcherServlet(context)), MAPPING_URL);
        handler.addEventListener(new ContextLoaderListener(context));
        return handler;
    }

    private static  WebApplicationContext webApplicationContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(MvcConfig.class);
        return context;
    }

}

上述代码通过jetty的api 完成对Spring Mvc Context的配置和设置。

3、通过ServletContainerInitializer 自动探测

Servlet 3.0 新增了接口;ServletContainerInitializer。Servlet规范规定了Servlet 容器在启动时依据Java SPI动态获取ServletContainerInitializer接口的服务(META-INF/services/javax.servlet.ServletContainerInitializer文件,内容就是ServletContainerInitializer实现类的全限定名),并执行其onStartup()方法,onStartup的方法定义如下:

public interface ServletContainerInitializer {

   void onStartup(Set<Class<?>> c, ServletContext ctx) throws 
ServletException;
}

在实现 Servlet(ontainerInitializer 时还可以通过 HandlesTypes 注解定义本实现类希望处理的类型,容器会将当前应用中所有这一类型(继承或者实现)的类放在方法onStartup参数中传递进来。如果不定义处理类型,或者应用中不存在相应的实现类,则集合参数c 为空。

Spring MVC提供了SpringServletContainerInitializer 来被Servlet 容器启动过程中探测调用。

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

}

基于以上Spring MVC提供的支持,可以让jetty自动探测加载相关的DispatchServlet的配置。

public class ContainerInitializerDemo implements WebApplicationInitializer {

    

    public static void main(String[] args) throws Exception {
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8090);
        server.setConnectors(new Connector[] { connector });
        String webappPath = JettyServer.class.getClassLoader().getResource(".").getPath();
        WebAppContext context = new WebAppContext( webappPath.substring(1),"/");


        MetaData metaData = context.getMetaData();
        Resource webappInitializer = Resource.newResource(JettyServer.class.getClassLoader().getResource("."));
        metaData.addContainerResource(webappInitializer);

        context.setConfigurations(new Configuration[] {
                new AnnotationConfiguration(),
                new WebInfConfiguration(), new EnvConfiguration() });
        server.setHandler(context);

        // 启动

        server.start();

        // 打印dump时的信息
        System.out.println(server.dump());

        // join当前线程
        server.join();
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(MvcConfig.class);
       ServletRegistration.Dynamic registration = servletContext.addServlet("app", new DispatcherServlet(context));
        registration.setLoadOnStartup(1);
       registration.addMapping("/app/*");
    }


}

MvcConfig的代码:

@Configuration
@ComponentScan(basePackages = { "com.test.mvc" })
@EnableWebMvc
public class MvcConfig {

}
点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
springMvc HandlerMethodArgumentResolver
SpringMvc在配置多个mvc:argumentresolvers(目前是分开在不同的配置文件)会出现覆盖问题;实际spring容器中只会有一个文件里配置的bean原因debug后发现,MVC实际是在调用一个name为org.springframework.web.servlet.mvc.method.annot
Stella981 Stella981
3年前
SpringBoot连接常见设置
SpringBoot集成了Servlet容器,因此我们可以方便的启动一个容器,并访问其中的接口。那么如何控制Servlet容器中的线程池呢?可以通过如下配置进行控制server:tomcat:appcectcount:1minspacethreads:1maxthreads:
Easter79 Easter79
3年前
SpringMVC+MyBatis(最新)
目前主流的WebMVC框架,除了Struts这个主力外,还有SpringMVC,主要是由于SpringMVC配置比较简单,使用起来也十分明了,非常灵活,与Spring集成较好,对RESTfulAPI的支持也比struts要好。MyBatis是ibatis的升级版,作为hibernate的老对手,它是一个可以自定义SQL、存储过程和高级映射
Easter79 Easter79
3年前
SpringMVC从认识到细化了解
\TOC\首发日期:20181101SpringMVC的介绍<br介绍:SpringMVC是一个Web层的MVC框架SpringMVC是基于servlet来处理web请求的,所有的请求都是先经过核心servlet再转交给对应的控制器。它与spring同属
Wesley13 Wesley13
3年前
activemq安全设置 设置admin的用户名和密码
ActiveMQ使用的是jetty服务器,打开conf/jetty.xml文件,找到<beanid"securityConstraint"class"org.eclipse.jetty.http.security.Constraint"    <propertyname"name"value"BASIC"/ 
Easter79 Easter79
3年前
SpringMVC用responsebody标签返回json的时候Error406
springmvc的好处就是可以用一个responsebody的标签直接将一个返回的对象转换成json首先,需要配置spring,将以下的bean配置到spring的配置文件中<bean class"org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandle
Easter79 Easter79
3年前
SpringMVC第一天HelloWorld
1,普通Servlet的流程是通过配置<servlet</servlet和<servletmapping</servletmapping来拦截请求交给对应的Servlet来处理使用SpringMVC需要配置一个SpringMVC自带的Servlet,DispatcherServlet,使用他来拦截请求交给SpringMVC处理 we
Stella981 Stella981
3年前
Jetty 源码分析
一、总括    你了解Jetty吗,就像我们所熟知的Tomcat一样,Jetty是一个免费的开放源码的100%纯Java的Http服务器和Servlet容器。    Jetty具备以下特点:    快速高效    。Jetty是最快的Servlet服务器之一    。Jetty可以处理上千
Stella981 Stella981
3年前
Jetty学习(一)
Jetty官方文档(学习新东西,看文档是最好的,有问题也应该最先去查询文档):http://www.eclipse.org/jetty/documentation/current/index.html1.HelloWorld(Jetty)首先,不介绍Jetty这个东西,暂且认为它是tomcat的轻量级版,先在Eclipse里跑起来,这才是
Easter79 Easter79
3年前
SpringBoot连接常见设置
SpringBoot集成了Servlet容器,因此我们可以方便的启动一个容器,并访问其中的接口。那么如何控制Servlet容器中的线程池呢?可以通过如下配置进行控制server:tomcat:appcectcount:1minspacethreads:1maxthreads:
Easter79 Easter79
3年前
SpringBoot2.x入门:引入web模块
前提这篇文章是《SpringBoot2.x入门》专辑的第3篇文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8。主要介绍SpringBoot的web模块引入,会相对详细地分析不同的Servlet容器(如Tomcat、Jetty等)的切换,以及该模块提供的Spring