JavaWeb项目中调用dll动态链接库

工作问题 专栏收录该内容
1 篇文章 0 订阅

介绍

  • 先简单介绍下遇到的问题,需要在web页面中增加身份证内的头像图片。头像图片已经通过身份证采集器采集并存储在Oracle数据库的blob中。但是存储的二进制数据是经过身份证采集器加密过,解码需要调用WltRS.dll的动态链接库方可把数据转换为普通图片数据。但是web项目中使用的是java,所以把调用dll遇到的问题,和解决方法记录下来。

Java调用dll动态链接库

  1. 最先尝试的是JNI的方法,由于没有时间再次写个dll,就把方法留下。

    如果有一个现有的.dll/.so文件,如果使用JNI技术调用,我们首先需要另外使用C语言写一个.dll/.so共享库,使用SUN规定的数据结构替代C语言的数据结构,调用已有的dll/so中公布的函数。
    然后再在Java中载入这个适配器dll/so,再编写Java native函数作为dll中函数的代理。经过2个繁琐的步骤才能在Java中调用本地代码。
    因此,很少有Java程序员愿意编写调用dll/.so库中的原生函数的java程序。这也使Java语言在客户端上乏善可陈。可以说JNI是Java的一大弱点!
    JNI 调用dll具体实现方法

  2. JNative调用dll
    这个方法比较简单,只需要下载JNative的文件,将JNativeCpp.dll文件放入system32文件夹中(.so文件是linux使用),java项目中引用JNative.jar包即可。具体实现代码如下:

public class WltRS {
    public static String GetBmp(byte[] wlt) throws NativeException, IllegalAccessException{
        JNative nGetBmp = new JNative("WltRS", "GetBmp");
        //设置第一个参数类型。
        nGetBmp.setParameter(0, Type.STRING, wlt);
        //设置第二个参数类型
        nGetBmp.setParameter(1,2);
        //设置返回值类型
        nGetBmp.setRetVal(Type.INT);
        //执行方法
        nGetBmp.invoke();
        return nGetBmp.getRetVal();
    }
    public static void main(String[] args) throws Exception{
        byte[] data = "C:\\test.wlt".getBytes();
        System.out.println(GetBmp(data).toString());
    }
}

使用此方法即可调用成功dll,也就将test.wlt文件转化为test.bmp文件(dll中GetBmp方法实现)。

Java将Blob存储为wlt文件

很简单的实现方法,提一下。

private void test() throws Exception{
        String sql = "***";
        try{
            Statement state = db.createStatement();
            ResultSet rs = state.executeQuery(sql);
            while(rs.next()){
                BLOB blob = (BLOB) rs.getBlob("pic");
                InputStream inputStream = blob.getBinaryStream();
                FileOutputStream fileOutputStream = new FileOutputStream("c:\\test.wlt");
                byte[] buf = new byte[1];
                int len = 0;
                while((len = inputStream.read(buf)) != -1) {
                fileOutputStream.write(buf, 0, len);
                }
                inputStream.close();
                fileOutputStream.close();     
            }
            rs.close();
            state.close();
            db.commit();
            }catch(SQLException e){
                db.rollback();
                e.printStackTrace();
        }
    }

将图片文件转化为Base64,用Ajax异步显示图片。我的环境用的IE8,这样显示的图片大小只能小于30K所以对图片进行了裁剪。具体代码如下:

private String GetImageStr(String imgFile)  
    {//将图片文件转化为字节数组字符串,并对其进行Base64编码处理  
        InputStream in = null;  
        //读取图片字节数组  
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try   
        {  
            in = new FileInputStream(imgFile);
            //对图片裁剪,宽度为80的等比例缩小
            Image img = ImageIO.read(in);
            int width = img.getWidth(null);
            int height = img.getHeight(null);
            BufferedImage image = new BufferedImage(80, height*80/width,BufferedImage.TYPE_INT_RGB );   
            Graphics gra = image.getGraphics();
            gra.drawImage(img, 0, 0, 80, height*80/width, null);
            ImageIO.write(image, "png", out);
            gra.dispose();
            in.close();
        }   
        catch (IOException e)   
        {  
            e.printStackTrace();  
        }  
        //对字节数组Base64编码  
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(out.toByteArray());//返回Base64编码过的字节数组字符串  
    }

正式发布使用,用的是64位window service 2008 ,was发布web项目,发现都无法调用到dll文件。发布注意点:

1.将需要调用的dll文件与JNativeCpp.dll文件一起放入system32中。
如果还是不能调用,再将这两个文件放入中间件的bin文件中,如:Tomcat或was的bin文件夹中。
2.JNative只适用于32位的系统,如果64位需要使用,则jdk和中间件都需要时32位的。
3.如果无法更换32位。就无法使用Jnative。可以使用Jacob的方法调用dll。
此方法支持32位,和64位。但是需要注意的是64位调用时,需要你的dll文件也是64位的才可以支持。
  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

chengxm123

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值