netty整合springmvc

    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服务发布。


项目的完整代码已经在https://github.com/linsongze/nettyholdspringmvc/



  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值