美文网首页
Centos7+Tomcat8验证码不显示问题

Centos7+Tomcat8验证码不显示问题

作者: StrongZhao | 来源:发表于2018-10-16 18:56 被阅读138次

    Centos7+Tomcat8验证码不显示问题

    问题描述:

    部署的项目在Mac下运行正常,验证码显示正常,但是把项目部署到正式环境上之后发现验证码不显示,直接访问验证码链接报错400缺少open-sans字体,添加字体不能解决问题,log日志没有报错信息显示。

    分析:

    项目中并没有使用这个字体,切生成二维码的字体也不是这个字体,所以可以断定肯定不是字体的问题,对比tomcat目录发现服务器上tomcat的temp目录被删了,创建一个temp文件刷新页面二维码显示正常

    哪生成二维码图片的显示和tomcat下的temp文件存不存有什么关系呢?

    二维码生成代码如下:

    OutputStream out = response.getOutputStream();
    ImageIO.write(image, "JPEG", out);
    out.close();
    

    查看ImageIO.write源码如下:

      public static boolean write(RenderedImage im,String formatName,OutputStream output) throws IOException {
            if (output == null) {
                throw new IllegalArgumentException("output == null!");
            }
            ImageOutputStream stream = null;
            try {
                stream = createImageOutputStream(output);//创建图片输出流
            } catch (IOException e) {
                throw new IIOException("Can't create output stream!", e);
            }
    
            try {
                return doWrite(im, getWriter(im, formatName), stream);
            } finally {
                stream.close();
            }
        }
    

    查看createImageOutputStream()源码如下:

    public static ImageOutputStream createImageOutputStream(Object output)
           throws IOException {
           if (output == null) {
               throw new IllegalArgumentException("output == null!");
           }
    
           Iterator iter;
           // Ensure category is present
           try {
               iter = theRegistry.getServiceProviders(ImageOutputStreamSpi.class,
                                                      true);
           } catch (IllegalArgumentException e) {
               return null;
           }
    
           boolean usecache = getUseCache() && hasCachePermission();//判断是否会使用cache文件
    
           while (iter.hasNext()) {
               ImageOutputStreamSpi spi = (ImageOutputStreamSpi)iter.next();
               if (spi.getOutputClass().isInstance(output)) {
                   try {
                       return spi.createOutputStreamInstance(output,
                                                             usecache,
                                                             getCacheDirectory());
                   } catch (IOException e) {
                       throw new IIOException("Can't create cache file!", e);
                   }
               }
           }
    
           return null;
       }
    
    

    查看hasCachePermission()源码如下:

    private static boolean hasCachePermission() {
        Boolean hasPermission = getCacheInfo().getHasPermission();
    
        if (hasPermission != null) {
            return hasPermission.booleanValue();
        } else {
            try {
                SecurityManager security = System.getSecurityManager();
                if (security != null) {
                    File cachedir = getCacheDirectory();
                    String cachepath;
                    /*
                     * 写得也很清楚,如果自己设置了 setCacheDirectory 那么会使用自定义的,否则调用getTempDir()
                     */
                    if (cachedir != null) {
                        cachepath = cachedir.getPath();
                    } else {
                        cachepath = getTempDir();
    
                        if (cachepath == null || cachepath.isEmpty()) {
                            getCacheInfo().setHasPermission(Boolean.FALSE);
                            return false;
                        }
                    }
    
                    // we have to check whether we can read, write,
                    // and delete cache files.
                    // So, compose cache file path and check it.
                    String filepath = cachepath;
                    if (!filepath.endsWith(File.separator)) {
                        filepath += File.separator;
                    }
                    filepath += "*";
    
                    security.checkPermission(new FilePermission(filepath, "read, write, delete"));
                }
            } catch (SecurityException e) {
                getCacheInfo().setHasPermission(Boolean.FALSE);
                return false;
            }
    
            getCacheInfo().setHasPermission(Boolean.TRUE);
            return true;
        }
    }
    

    查看getTempDir()源码如下:

    /** 
      * Returns the default temporary (cache) directory as defined by the 
      * java.io.tmpdir system property. 
      */  
     private static String getTempDir() {  
         GetPropertyAction a = new GetPropertyAction("java.io.tmpdir");  
         return (String)AccessController.doPrivileged(a);  
     }  
    

    从上面代码可以看出来是读取了变量java.io.tmpdir,而我们tomcat启动的时候会tomcat 启动的时候,调用jvm会设置 java.io.tmpdir参数 使用temp文件夹,所以生成图片的程序tomcat目录下必须要有temp文件夹

    image.png

    相关文章

      网友评论

          本文标题:Centos7+Tomcat8验证码不显示问题

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