解决自定义字体产生临时文件消耗硬盘的问题,以及解决总分操作系统下无法读到字体文件的问题
This commit is contained in:
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -10,7 +10,7 @@
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="EasyCaptcha" target="6" />
|
||||
<module name="EasyCaptcha" target="8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
</project>
|
||||
13
.idea/libraries/Maven__junit_junit_4_7.xml
generated
13
.idea/libraries/Maven__junit_junit_4_7.xml
generated
@@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: junit:junit:4.7">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.m2/repository/junit/junit/4.7/junit-4.7.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$USER_HOME$/.m2/repository/junit/junit/4.7/junit-4.7-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.m2/repository/junit/junit/4.7/junit-4.7-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,16 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6">
|
||||
<component name="FacetManager">
|
||||
<facet type="web" name="Web">
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/web/WEB-INF/web.xml" />
|
||||
</descriptors>
|
||||
<webroots>
|
||||
<root url="file://$MODULE_DIR$/web" relative="/" />
|
||||
</webroots>
|
||||
<sourceRoots>
|
||||
<root url="file://$MODULE_DIR$/src/main/java" />
|
||||
<root url="file://$MODULE_DIR$/src/main/resources" />
|
||||
</sourceRoots>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.7" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,5 @@
|
||||
Manifest-Version: 1.0
|
||||
Created-By: IntelliJ IDEA
|
||||
Built-By: zrh
|
||||
Build-Jdk: 1.8.0_251
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
15
classes/artifacts/EasyCaptcha_Web_exploded/WEB-INF/web.xml
Normal file
15
classes/artifacts/EasyCaptcha_Web_exploded/WEB-INF/web.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
|
||||
version="4.0">
|
||||
<!-- 图形验证码servlet -->
|
||||
<servlet>
|
||||
<servlet-name>CaptchaServlet</servlet-name>
|
||||
<servlet-class>com.wf.captcha.servlet.CaptchaServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>CaptchaServlet</servlet-name>
|
||||
<url-pattern>/captcha</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
||||
10
classes/artifacts/EasyCaptcha_Web_exploded/index.html
Normal file
10
classes/artifacts/EasyCaptcha_Web_exploded/index.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>验证码测试</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="/captcha" width="130px" height="48px" />
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.wf.captcha.base;
|
||||
|
||||
import com.wf.captcha.utils.FontsUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.*;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
@@ -275,7 +274,7 @@ public abstract class Captcha extends Randoms {
|
||||
}
|
||||
|
||||
public void setFont(int font, int style, float size) throws IOException, FontFormatException {
|
||||
this.font = Font.createFont(Font.TRUETYPE_FONT, new File(getClass().getResource("/" + FONT_NAMES[font]).getFile())).deriveFont(style, size);
|
||||
this.font = FontsUtil.getFont(FONT_NAMES[font], style, size);
|
||||
}
|
||||
|
||||
public int getLen() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.wf.captcha.servlet;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
@@ -7,6 +8,9 @@ import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.wf.captcha.GifCaptcha;
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import com.wf.captcha.utils.CaptchaUtil;
|
||||
|
||||
/**
|
||||
@@ -18,7 +22,16 @@ public class CaptchaServlet extends HttpServlet {
|
||||
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
CaptchaUtil.out(request, response);
|
||||
// SpecCaptcha captcha = new SpecCaptcha(130, 48, 6);
|
||||
GifCaptcha captcha = new GifCaptcha(130, 48, 6);
|
||||
|
||||
// 设置内置字体
|
||||
try {
|
||||
captcha.setFont(Captcha.FONT_10);
|
||||
} catch (FontFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
CaptchaUtil.out(captcha, request, response);
|
||||
}
|
||||
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
|
||||
107
src/main/java/com/wf/captcha/utils/FileUtil.java
Normal file
107
src/main/java/com/wf/captcha/utils/FileUtil.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package com.wf.captcha.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 文件操作工具类,此类源码从org.apache.commons.io.FileUtils中复制
|
||||
*
|
||||
* @author zrh 455741807@qq.com
|
||||
* @date 2022-05-07
|
||||
*/
|
||||
public class FileUtil {
|
||||
public static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||
public static final int EOF = -1;
|
||||
|
||||
/**
|
||||
* 文件流复制
|
||||
* @param inputStream
|
||||
* @param file
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void copyToFile(final InputStream inputStream, final File file) throws IOException {
|
||||
try (OutputStream out = openOutputStream(file)) {
|
||||
copy(inputStream, out);
|
||||
}
|
||||
}
|
||||
|
||||
public static FileOutputStream openOutputStream(final File file) throws IOException {
|
||||
return openOutputStream(file, false);
|
||||
}
|
||||
|
||||
public static FileOutputStream openOutputStream(final File file, final boolean append) throws IOException {
|
||||
Objects.requireNonNull(file, "file");
|
||||
if (file.exists()) {
|
||||
requireFile(file, "file");
|
||||
requireCanWrite(file, "file");
|
||||
} else {
|
||||
createParentDirectories(file);
|
||||
}
|
||||
return new FileOutputStream(file, append);
|
||||
}
|
||||
|
||||
private static File requireFile(final File file, final String name) {
|
||||
Objects.requireNonNull(file, name);
|
||||
if (!file.isFile()) {
|
||||
throw new IllegalArgumentException("Parameter '" + name + "' is not a file: " + file);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
private static void requireCanWrite(final File file, final String name) {
|
||||
Objects.requireNonNull(file, "file");
|
||||
if (!file.canWrite()) {
|
||||
throw new IllegalArgumentException("File parameter '" + name + " is not writable: '" + file + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public static File createParentDirectories(final File file) throws IOException {
|
||||
return mkdirs(getParentFile(file));
|
||||
}
|
||||
|
||||
private static File mkdirs(final File directory) throws IOException {
|
||||
if ((directory != null) && (!directory.mkdirs() && !directory.isDirectory())) {
|
||||
throw new IOException("Cannot create directory '" + directory + "'.");
|
||||
}
|
||||
return directory;
|
||||
}
|
||||
|
||||
private static File getParentFile(final File file) {
|
||||
return file == null ? null : file.getParentFile();
|
||||
}
|
||||
|
||||
public static int copy(final InputStream inputStream, final OutputStream outputStream) throws IOException {
|
||||
final long count = copyLarge(inputStream, outputStream);
|
||||
if (count > Integer.MAX_VALUE) {
|
||||
return EOF;
|
||||
}
|
||||
return (int) count;
|
||||
}
|
||||
|
||||
public static long copyLarge(final InputStream inputStream, final OutputStream outputStream)
|
||||
throws IOException {
|
||||
return copy(inputStream, outputStream, DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public static long copy(final InputStream inputStream, final OutputStream outputStream, final int bufferSize)
|
||||
throws IOException {
|
||||
return copyLarge(inputStream, outputStream, byteArray(bufferSize));
|
||||
}
|
||||
|
||||
public static long copyLarge(final InputStream inputStream, final OutputStream outputStream, final byte[] buffer)
|
||||
throws IOException {
|
||||
Objects.requireNonNull(inputStream, "inputStream");
|
||||
Objects.requireNonNull(outputStream, "outputStream");
|
||||
long count = 0;
|
||||
int n;
|
||||
while (EOF != (n = inputStream.read(buffer))) {
|
||||
outputStream.write(buffer, 0, n);
|
||||
count += n;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static byte[] byteArray(final int size) {
|
||||
return new byte[size];
|
||||
}
|
||||
}
|
||||
75
src/main/java/com/wf/captcha/utils/FontsUtil.java
Normal file
75
src/main/java/com/wf/captcha/utils/FontsUtil.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package com.wf.captcha.utils;
|
||||
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static java.security.AccessController.doPrivileged;
|
||||
|
||||
/**
|
||||
* 解决自定义字体读取时,产生.tmp临时文件耗磁盘的问题。
|
||||
*
|
||||
* 解决思路:
|
||||
* Font类的createFont有个重载方法–>java.awt.Font#createFont(int, java.io.File),
|
||||
* 不产生临时文件获取字体代码实现
|
||||
* <code>
|
||||
* URL url = FontLoader.class.getResource("font/SourceHanSansCN-Regular.otf");
|
||||
* String pathString = url.getFile();
|
||||
* Font selfFont = Font.createFont(Font.TRUETYPE_FONT, new File(pathString));
|
||||
* </code>
|
||||
* 上面的解决方案会导致另一个问题,字体文件在生产环境是在jar包里,部分操作系统环境下,直接读取读取不到,只能通过流的方式获取。
|
||||
*
|
||||
* 因此,本方案采用的办法是把jar包中的字体文件复制到java.io.tmpdir临时文件夹中
|
||||
* ,再采用<code>java.awt.Font#createFont(int, java.io.File)</code>的方式产生字体,既解决了临时文件tmp消耗磁盘的问题,也解决了
|
||||
* 部分操作系统下读不到文件的问题。
|
||||
*
|
||||
* @author zrh 455741807@qq.com
|
||||
* @date 2022-05-07
|
||||
*
|
||||
*/
|
||||
public class FontsUtil {
|
||||
private static final Path tmpdir = Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
|
||||
|
||||
/**
|
||||
* 手动复制字体文件到临时目录. 调用传文件的构造方法创建字体
|
||||
* @param fontName 字体文件名称
|
||||
* @return
|
||||
*/
|
||||
public static Font getFont(String fontName, int style, float size) {
|
||||
Font font = null;
|
||||
|
||||
File tempFontFile = new File(tmpdir.toUri().getPath() + fontName);
|
||||
if(!tempFontFile.exists()){
|
||||
//临时文件不存在
|
||||
copyTempFontFile(fontName, tempFontFile);
|
||||
}
|
||||
if(tempFontFile.exists()) {
|
||||
try {
|
||||
font = Font.createFont(Font.TRUETYPE_FONT, tempFontFile).deriveFont(style, size);;
|
||||
} catch (FontFormatException | IOException e) {
|
||||
e.printStackTrace();
|
||||
tempFontFile.delete();
|
||||
}
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制字体文件到临时文件目录
|
||||
* @param fontName
|
||||
* @param tempFontFile
|
||||
*/
|
||||
private static synchronized void copyTempFontFile(String fontName, File tempFontFile){
|
||||
try(InputStream is = FontsUtil.class.getResourceAsStream("/" + fontName)){
|
||||
FileUtil.copyToFile(is, tempFontFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
15
web/WEB-INF/web.xml
Normal file
15
web/WEB-INF/web.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
|
||||
version="4.0">
|
||||
<!-- 图形验证码servlet -->
|
||||
<servlet>
|
||||
<servlet-name>CaptchaServlet</servlet-name>
|
||||
<servlet-class>com.wf.captcha.servlet.CaptchaServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>CaptchaServlet</servlet-name>
|
||||
<url-pattern>/captcha</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
||||
10
web/index.html
Normal file
10
web/index.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>验证码测试</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="/captcha" width="130px" height="48px" />
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user