netty整合springmvc

作者: 架构师springboot | 来源:发表于2018-10-14 15:33 被阅读2次

http协议是基于TCP的一种应用层协议,因为我们可以自己通过tcp的数据来进行编解码http协议。一般情况下,我们都是通过request对象和response对象进行与用户进行交互的。

    netty是一款对用户非常友好的网络框架,更甚者提供了大量的基于tcp的用户层的协议封装,我们可以直接使用,因为在netty注册编解码器的时候,我们只需要加上netty自带的http的编解码器,就可以在接收和发送数据的时候采用request对象和response对象。

        pipeline.addLast("decoder", new HttpRequestDecoder());

        pipeline.addLast("aggregator", new HttpChunkAggregator(65536));

        pipeline.addLast("encoder", new HttpResponseEncoder());

    这样子,初步的我们的netty已经可以与客户端之间进行http协议的通讯,但是这种通讯是属于静态的内容的,没有办法与本文所说结合springmvc借助springmvc的controller来处理业务逻辑。还记得springmvc的入口吗?org.springframework.web.servlet.DispatcherServlet这个servlet就是springmvc的入口,其实思路就是我们只需要调用这个servlet的service方法,然后里面的处理就会直接给springmvc接管了,因此我们要初始化这个servlet。

    private final DispatcherServlet dispatcherServlet;

    public DispatcherServletChannelInitializer() throws ServletException {

    MockServletContext servletContext = new MockServletContext();

    MockServletConfig servletConfig = new MockServletConfig(servletContext);

        servletConfig.addInitParameter("contextConfigLocation","classpath:/META-INF/spring/root-context.xml");

        servletContext.addInitParameter("contextConfigLocation","classpath:/META-INF/spring/root-context.xml");

    //AnnotationConfigWebApplicationContext wac = new AnnotationConfigWebApplicationContext();

        XmlWebApplicationContext wac = new XmlWebApplicationContext();//采用xml的配置形式加载spring文件,初始化springmvc的context

        //ClassPathXmlApplicationContext wac = new ClassPathXmlApplicationContext();

wac.setServletContext(servletContext);

wac.setServletConfig(servletConfig);

        wac.setConfigLocation("classpath:/servlet-context.xml");

    //wac.register(WebConfig.class);

    wac.refresh();

    this.dispatcherServlet = new DispatcherServlet(wac);

    this.dispatcherServlet.init(servletConfig);

}

已经存在servlet,要调用servlet的service接口,让我们看看servlet的service方法定义。

protected void service(HttpServletRequest request, HttpServletResponse response)

这个service方法的参数是HttpServletRequest和HttpServletResponse,因为我们接下来的目标就是将netty的HttpRequest和HttpResponse对象与servlet的对象进行相互转换。我采用了springtest提供的用来模拟HttpServletRequest和HttpServletResponse的类,这两个类也是它们的子类。

org.springframework.mock.web.MockHttpServletRequest;org.springframework.mock.web.MockHttpServletResponse;

    @Override

    public void messageReceived(ChannelHandlerContext ctx, HttpRequest request) throws Exception {

        if (!request.getDecoderResult().isSuccess()) {

            sendError(ctx, BAD_REQUEST);

            return;

        }

MockHttpServletRequest servletRequest = createServletRequest(request);

        MockHttpServletResponse servletResponse = new MockHttpServletResponse();

this.servlet.service(servletRequest, servletResponse);

        HttpResponseStatus status = HttpResponseStatus.valueOf(servletResponse.getStatus());

HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status);

for (String name : servletResponse.getHeaderNames()) {

for (Object value : servletResponse.getHeaderValues(name)) {

response.addHeader(name, value);

}

}

        // Write the initial line and the header.

        ctx.write(response);

        InputStream contentStream = new ByteArrayInputStream(servletResponse.getContentAsByteArray());

// Write the content.

        ChannelFuture writeFuture = ctx.write(new ChunkedStream(contentStream));

        writeFuture.addListener(ChannelFutureListener.CLOSE);

    }

最后直接在netty的回调方法中,进行处理和转换就OK了。遗憾的是,因为在代码里面并没有整合jsp和servlet容器,容易没办法处理正常的jsp页面,只能够将其作为http服务发布。

欢迎工作一到五年的Java工程师朋友们加入Java架构开发:855801563

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代

相关文章

网友评论

    本文标题:netty整合springmvc

    本文链接:https://www.haomeiwen.com/subject/vzozaftx.html