基于netty的浏览器客户端打印控件实现

本文介绍了一种基于Netty实现的浏览器客户端打印控件,解决了静默打印PDF文件的需求,避免了安装第三方控件。通过Java NIO和Spring Boot的尝试,最终选择了Netty来构建轻量级HTTP服务,实现在Firefox、Chrome和IE浏览器中稳定工作。项目代码可在GitHub找到。
摘要由CSDN通过智能技术生成

项目地址:https://github.com/w414034207/print-netty

业务场景

给客户开发一个web管理系统时,客户要求能够在浏览器点击打印,直接使用客户端的本地打印机打印服务端的文件,打印配置可以在网页进行设置。
客户要求静默打印,用户不需要看打印预览页面,可以打印服务端动态生成的PDF文件,可以在网页上选择打印份数,默认双面打印。

思路

网上看了各种提供打印的方式,使用js的一些打印控件都不符合要求,PDF文件中的电子签名解析不出来
还试用了两种收费的打印控件,都是需要在客户端安装启动一个可执行文件。
下图为当时试过的打印方式
当时试过的打印方式
其中一个收费的控件能一定程度满足我们的需求,直接传URL就能打印对应的PDF文件。且不会丢失PDF文件中的电子签名。(即上图中的第一个button对应的,简写是jcp,可以静默打印,也可以传各种打印参数,缺点是:1. 打印方法的回调不能确定是否打印成功;2. 如果url没有返回pdf,回调不会被调用;3. 收费)

这时我就想,如果考虑客户端安装控件的方式,好像自己写一个控件问题也不大:

  1. 实现一个http服务,可接收http请求,被请求时可用java调用打印机进行打印;
  2. 浏览器客户端请求本地一个固定端口即可访问到该服务;

技术选择

Spring Boot

现成的http服务,我直接就写了一个,验证上面思路的可行性,实验之后确实可以在浏览器端打印PDF文件;但是问题就是太大了,由于我的功能很简单,而使用了Spring Boot之后,运行时内存都200M以上,这对用户的机器性能就有可能造成较大的影响;

Java NIO

由于当时刚好在学习Java NIO的相关知识,既然Spring Boot现成的服务太大了,我或许可以自己实现http协议的编解码,使用Java NIO实现http服务,使服务更轻量,然后我就舍弃了Spring Boot,改用Java NIO实现(这个代码,在github上是Private的,如果有感兴趣的盆友可以发消息找我要);

netty

NIO版本的已经确认可以在FireFox、Chrome浏览器稳定使用,但是在使用IE进行测试时,经常会出现请求消息读取不完整的情况,我自己实现的http协议看来还需要优化。考虑到自己写的http协议还是太简陋,优化的空间很大,成本不好说。所以我决定还是使用netty提供的现成的http支持,用netty实现http服务,以兼顾轻量和稳定。

实现

netty实现http服务端
  1. 创建处理http请求的Handler(这里只贴出主要的方法,还有两个必须实现的接口方法没有贴)
@ChannelHandler.Sharable
public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
   

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
   

        DefaultFullHttpResponse response = executeRequest(msg);

        HttpHeaders heads = response.headers();
        // 返回内容的MIME类型
        heads.add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN + "; charset=UTF-8");
        // 响应体的长度
        heads.add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
        // 允许跨域访问
        heads.add(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*");

        // 响应给客户端
        ctx.write(response);
    }
    private DefaultFullHttpResponse executeRequest(FullHttpRequest msg) throws UnsupportedEncodingException {
   
        // 200
        HttpResponseStatus responseStatus = HttpResponseStatus.OK;
        String returnMsg = "";
        try {
   
            // 自己实现的保存http请求信息的类
            HttpRequest httpRequest = new HttpRequest(msg);
            Class<PrintController> printControllerClass = PrintController.class;
            Method invokeMethod = printControllerClass.getMethod(httpRequest.getMethod(), HttpRequest.class)
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值