學習下識別圖片中的文字,找到了Tess4j圖文識別的方式,于是就初步探究下,玩下識別驗證碼。
1、以3.4.2版本為例,下載Tess4j-3.4.2-src.zip。
2、下載中文字庫,chi_sim.traineddata。
下載Tess4j參考:
http://sourceforge.net/projects/tess4j/
字庫下載參考:
https://github.com/tesseract-ocr/tessdata/tree/3.04.00
api文檔參考:
http://tess4j.sourceforge.net/docs/docs-3.4/
1、解壓Tess4J-3.4.2-src.zip。
2、把根目錄的lib和dist相關jar拷貝到你的項目lib中。
3、再把tessdata目錄拷貝到你的項目根目錄中。
4、再把中文字庫放入tessdata目錄。
5、dll不用理,Tess4j.jar已經包含。
6、如果遇到異常,Error: Invalid memory access,Error opening data file ./tessdata/eng.traineddata說明tessdata路徑不對。
壓縮包目錄:
如果是使用maven:
就在pom.xml加入即可。
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>3.4.2</version>
</dependency>
我的項目test for java結構:
Tess4j依賴jar參考:
commons-beanutils-1.9.2.jar
commons-io-2.6.jar
commons-logging-1.2.jar
ghost4j-1.0.1.jar
hamcrest-core-1.3.jar
itext-2.1.7.jar
jai-imageio-core-1.3.1.jar
jboss-vfs-3.2.12.Final.jar
jcl-over-slf4j-1.7.25.jar
jna-4.1.0.jar
jul-to-slf4j-1.7.25.jar
junit-4.12.jar
lept4j-1.6.2.jar
log4j-1.2.17.jar
log4j-over-slf4j-1.7.25.jar
logback-classic-1.2.3.jar
logback-core-1.2.3.jar
slf4j-api-1.7.25.jar
xmlgraphics-commons-1.5.jar
官方簡單例子:
package net.sourceforge.tess4j.example;
import java.io.File;
import net.sourceforge.tess4j.*;
public class TesseractExample {
public static void main(String[] args) {
File imageFile = new File("eurotext.tif");
ITesseract instance = new Tesseract(); // JNA Interface Mapping
// ITesseract instance = new Tesseract1(); // JNA Direct Mapping
try {
String result = instance.doOCR(imageFile);
System.out.println(result);
} catch (TesseractException e) {
System.err.println(e.getMessage());
}
}
}
我的初探例子:
package com.weizhixi;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.util.ImageHelper;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
public class Test {
public static void main(String[] args) throws Exception{
testEn();
//testZh();
}
//使用英文字庫 - 識別圖片
public static void testEn() throws Exception {
File imageFile = new File("C:/Users/XQ/Desktop/en.png");
BufferedImage image = ImageIO.read(imageFile);
//對圖片進行處理
image = convertImage(image);
ITesseract instance = new Tesseract();//JNA Interface Mapping
String result = instance.doOCR(image); //識別
System.out.println(result);
}
//使用中文字庫 - 識別圖片
public static void testZh() throws Exception {
File imageFile = new File("C:/Users/XQ/Desktop/zh.png");
BufferedImage image = ImageIO.read(imageFile);
//對圖片進行處理
//image = convertImage(image);
ITesseract instance = new Tesseract();//JNA Interface Mapping
instance.setLanguage("chi_sim");//使用中文字庫
String result = instance.doOCR(image); //識別
System.out.println(result);
}
//對圖片進行處理 - 提高識別度
public static BufferedImage convertImage(BufferedImage image) throws Exception {
//按指定寬高創建一個圖像副本
//image = ImageHelper.getSubImage(image, 0, 0, image.getWidth(), image.getHeight());
//圖像轉換成灰度的簡單方法 - 黑白處理
image = ImageHelper.convertImageToGrayscale(image);
//圖像縮放 - 放大n倍圖像
image = ImageHelper.getScaledInstance(image, image.getWidth() * 3, image.getHeight() * 3);
return image;
}
}
處理傾斜圖片:
如果圖片字體傾斜的,可以用下面代碼糾正
BufferedImage bi = ImageIO.read(imageFile);
ImageDeskew id = new ImageDeskew(bi);
double imageSkewAngle = id.getSkewAngle(); //獲取傾斜角度
if ((imageSkewAngle > 0.05d || imageSkewAngle < -(0.05d))) {
bi = ImageHelper.rotateImage(bi, -imageSkewAngle); //糾偏圖像
}
測試1:
測試一張英文截圖en.png。
未使用圖像簡單處理,運行讀取圖片文字:
發現有幾次無法準確識別。
使用convertImage方法對圖像簡單處理,運行讀取圖片文字:
發現已經完全識別了。
測試2:
測試一張中文圖片zh.png
用不用convertImage,測試結果都正常:
測試3:
來點復雜的圖片:
來看看識別輸出:
1、未使用圖像處理
2、使用圖像處理
發現識別度提高了很多,但部分還是未能夠識別。
測試4:
識別干擾度比較低的簡單驗證碼
識別結果:已經正確識別了。
經測試多張各種驗證碼,干擾度比較大的,扭曲字體的驗證碼不能識別。
訓字庫能提高中文字庫的識別度。
需要下載中文字庫:chi_sim.traindata
需要下載tesseract-ocr安裝:tesseract-ocr-setup.exe
需要下載jTessBoxEditor用于修改box文件
至于怎么訓字庫,這里不展開說了。
初探了一天,發現初級簡單應用Tess4j:
1、只能識別幾乎沒有干擾,比較清晰的圖片。
2、對圖片灰度處理和放大處理,能提高識別度,但不是一定能起作用。
3、如果不準確的識別,可能要去訓字庫了,如測試識別圖中的逗號,已經變成偏上的點了。
4、識別度受字體顏色、大小、清晰度、干擾度、扭曲、傾斜等度影響。
5、官方還提供了一些test例子,還有很多操作和應用。
初級應用只是簡單的識別,能識別復雜度很大的圖片文字,那是要很多牛B技術和邏輯的大神級操作。
如果想識別度很高很高幾乎所有都能識別,又要快速集成、建議還是調用第三方識別API了,有些要收費的有些不用收費但有調用頻次限制。
由于資源太大,我就不上傳到我網站了。
請到我的網盤下載:
鏈接:https://pan.baidu.com/s/1dHje9pR
密碼:z0bi
內含:
1、項目:基于maven_test4j例子項目.zip
2、官方Tess4j:Tess4J-3.4.2-src.zip
3、中文訓字庫:chi_sim.traineddata
轉自:https://www.weizhixi.com/article/59.html
要功能點:
Spring Boot Web 整合 JasperReports,在瀏覽器地址欄輸入訪問地址會直接下載 PDF 報表文件;整合過程中遇到的兩個比較費時間的問題:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.19.1</version>
<exclusions>
<exclusion>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-fonts</artifactId>
<version>6.19.1</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
報表文件名稱:employees-details.jrxml
報表文件路徑:src\main\resources\employees-details.jrxml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.19.1.final using JasperReports Library version 6.19.1-867c00bf88cd4d784d404379d6c05e1b419e8a4c -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Employee" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="37175dba-8b89-474d-8341-09d431dce38f">
<style name="Table_TH" mode="Opaque" backcolor="#F0F8FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<style name="Table_CH" mode="Opaque" backcolor="#BFE1FF">
<box>
<pen lineWidth="0.5" lineColor="#000000"/>
<topPen lineWidth="0.5" lineColor="#000000"/>
<leftPen lineWidth="0.5" lineColor="#000000"/>
<bottomPen lineWidth="0.5" lineColor="#000000"/>
<rightPen lineWidth="0.5" lineColor="#000000"/>
</box>
</style>
<subDataset name="Dataset1" uuid="01ae53ec-87c9-41de-867d-bd79f5d4e77c">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="id" class="java.lang.Integer"/>
<field name="name" class="java.lang.String"/>
<field name="role" class="java.lang.String"/>
<field name="address" class="java.lang.String"/>
<sortField name="id"/>
<variable name="totalEmployees" class="java.lang.Integer" calculation="DistinctCount">
<variableExpression><![CDATA[$F{id}]]></variableExpression>
</variable>
</subDataset>
<parameter name="CompanyName" class="java.lang.String"/>
<parameter name="employeeData" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="name" class="java.lang.String"/>
<field name="id" class="java.lang.Integer"/>
<field name="role" class="java.lang.String"/>
<field name="address" class="java.lang.String"/>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="86" splitType="Stretch">
<frame>
<reportElement mode="Opaque" x="0" y="0" width="555" height="86" backcolor="#3BE3E3" uuid="57f80b95-2c82-4855-8b4f-797057ea6a99"/>
<image scaleImage="FillFrame">
<reportElement x="82" y="0" width="410" height="40" uuid="c21b5d52-4d05-448d-a001-a0cd19a9aeb2"/>
<imageExpression><![CDATA["E:/1.png"]]></imageExpression>
</image>
<textField>
<reportElement style="Table_TH" mode="Transparent" x="90" y="50" width="400" height="30" backcolor="#FFFFFF" uuid="15957312-bfcc-43e7-ad7c-8cdb97c4197b">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</reportElement>
<box padding="0">
<pen lineWidth="1.0" lineStyle="Solid"/>
<topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
<leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
<bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
<rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
</box>
<textElement>
<font fontName="華文宋體" size="20" isBold="true" isItalic="true" isUnderline="true"/>
</textElement>
<textFieldExpression><![CDATA[$P{CompanyName}]]></textFieldExpression>
</textField>
</frame>
</band>
</title>
<pageHeader>
<band height="31" splitType="Stretch">
<line>
<reportElement x="0" y="15" width="555" height="1" uuid="04a9c4d5-af68-4738-b280-249876a779f3">
<property name="com.jaspersoft.studio.unit.height" value="px"/>
</reportElement>
<graphicElement>
<pen lineStyle="Dashed"/>
</graphicElement>
</line>
</band>
</pageHeader>
<detail>
<band height="170" splitType="Stretch">
<property name="com.jaspersoft.studio.unit.height" value="px"/>
<componentElement>
<reportElement x="0" y="0" width="555" height="170" uuid="58650125-3653-4fa6-9154-b9c084419a71">
<property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
<property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/>
<property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/>
<property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/>
</reportElement>
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<datasetRun subDataset="Dataset1" uuid="33e34648-091e-48f9-b2c9-2defadbd03fb">
<dataSourceExpression><![CDATA[$P{employeeData}]]></dataSourceExpression>
</datasetRun>
<jr:column width="100" uuid="fed73b20-211a-48ef-bf45-eb5f50e0d41b">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/>
<jr:tableFooter style="Table_TH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="b219724f-df88-4066-8fc3-db986efed088"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Total Employees=]]></text>
</staticText>
</jr:tableFooter>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="6e4a6eb9-7503-46c2-b199-cb78736d4827"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<text><![CDATA[ID]]></text>
</staticText>
</jr:columnHeader>
<jr:columnFooter style="Table_CH" height="30" rowSpan="1"/>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="e04148fe-4406-4817-bf7c-a75a1837a834"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="100" uuid="c805b32b-9978-4ad9-93c8-64fb6ebdc310">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column2"/>
<jr:tableFooter style="Table_TH" height="30" rowSpan="1">
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="8b6f3603-5468-4ed8-92d6-2744856cfbec"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$V{totalEmployees}]]></textFieldExpression>
</textField>
</jr:tableFooter>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="ae32a33c-1f5c-4045-b8d6-738226f2881e"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<text><![CDATA[員工姓名]]></text>
</staticText>
</jr:columnHeader>
<jr:columnFooter style="Table_CH" height="30" rowSpan="1"/>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="ce7df570-525d-4bb1-9ed3-a63c0b387bbd"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="40" uuid="bd04119c-8493-4333-952a-2aeac29db62b">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column3"/>
<jr:tableFooter style="Table_TH" height="30" rowSpan="1"/>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="40" height="30" uuid="37ee0454-22df-4056-a40e-f52f82d29f95"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<text><![CDATA[角色]]></text>
</staticText>
</jr:columnHeader>
<jr:columnFooter style="Table_CH" height="30" rowSpan="1"/>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="40" height="30" uuid="a789a863-4232-4279-8a66-be83206747fe"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<textFieldExpression><![CDATA[$F{role}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="200" uuid="f32f724a-24c9-4887-ba41-5957dd0fed1d">
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column4"/>
<jr:tableFooter style="Table_TH" height="30" rowSpan="1"/>
<jr:columnHeader style="Table_CH" height="30" rowSpan="1">
<staticText>
<reportElement x="0" y="0" width="200" height="30" uuid="ced8b636-0cef-488f-89c4-9988b81415db"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<text><![CDATA[地址]]></text>
</staticText>
</jr:columnHeader>
<jr:columnFooter style="Table_CH" height="30" rowSpan="1">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</jr:columnFooter>
<jr:detailCell style="Table_TD" height="30">
<textField>
<reportElement x="0" y="0" width="200" height="30" uuid="958c39bd-fd6f-4414-9700-579e0c8ee7d9"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="華文宋體"/>
</textElement>
<textFieldExpression><![CDATA[$F{address}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
</componentElement>
</band>
</detail>
<pageFooter>
<band height="50" splitType="Stretch">
<textField>
<reportElement x="350" y="20" width="100" height="30" uuid="9ab9485d-d510-496f-9dcd-dae944a4ae43"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA["Page " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="455" y="20" width="100" height="30" uuid="a534e5d1-aa1b-4a87-9149-d7a052cbc01f"/>
<textFieldExpression><![CDATA[" of " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</pageFooter>
</jasperReport>
字體文件位置:src\main\resources\static\font\chinese.stsong.ttf
字體配置文件位置:src\main\resources\static\font\fonts.xml
配置文件內容
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<fontFamily name="華文宋體">
<normal>static/font/chinese.stsong.ttf</normal>
<bold>static/font/chinese.stsong.ttf</bold>
<italic>static/font/chinese.stsong.ttf</italic>
<boldItalic>static/font/chinese.stsong.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'華文宋體', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'華文宋體', Arial, Helvetica, sans-serif</export>
</exportFonts>
</fontFamily>
</fontFamilies>
在 classpath 路徑下(application.properties 同級)創建 Jasper 拓展文件 jasperreports_extension.properties
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.lobstertwo=static/font/fonts.xml
@Data
@NoArgsConstructor
public class Employee {
private int id;
private String name;
private String role;
private String address;
public Employee(int id, String name, String role, String address) {
this.id=id;
this.name=name;
this.role=role;
this.address=address;
}
}
@RestController
public class EmployeeController {
@GetMapping("/employee/records/report")
public ResponseEntity<byte[]> getEmployeeRecordReport() {
try {
// 測試數據
List<Employee> empLst=createTestData();
// 報表需要的動態參數
Map<String, Object> empParams=new HashMap<String, Object>();
empParams.put("CompanyName", "Spring Boot 整合 JasperReports");
empParams.put("employeeData", new JRBeanCollectionDataSource(empLst));
// 編譯
JasperReport jasperReport=JasperCompileManager.compileReport(
ResourceUtils.getFile("classpath:employees-details.jrxml").getAbsolutePath()
);
// 填充數據
JasperPrint jasperPrint=JasperFillManager.fillReport(jasperReport, empParams, new JREmptyDataSource());
// 導出報表
HttpHeaders headers=new HttpHeaders();
// 設置響應格式:PDF
headers.setContentType(MediaType.APPLICATION_PDF);
// 設置文件名稱
headers.setContentDispositionFormData("filename", "employees-details.pdf");
return new ResponseEntity<byte[]>(JasperExportManager.exportReportToPdf(jasperPrint), headers, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
private List<Employee> createTestData() {
List<Employee> resultList=new ArrayList<>();
resultList.add(new Employee(1, "汪小成", "程序員", "山東省濟寧市任城區"));
resultList.add(new Employee(2, "孫小順", "部門經理", "安徽省合肥市蜀山區"));
return resultList;
}
}
在谷歌瀏覽器地址欄輸入 http://localhost:9000/employee/records/report 會直接彈出保存文件的對話框,實際效果如下:
itext-2.1.7.js8.jar 可以在如下地址下載:
https://jaspersoft.jfrog.io/ui/native/third-party-ce-artifacts/com/lowagie/itext/2.1.7.js8/
這里搜集了用來構建應用程序的工具。
編程操作Java字節碼的函數庫。
軟件度量和質量評估工具。
創建分析器、解釋器和編譯器的框架。
支持持續集成、測試和應用發布的工具。
簡化數據庫交互的工具、庫。
處理日期和時間的函數庫。
幫助代碼實現控制反轉模式的函數庫。
從基礎層次上改進開發流程。
用來開發分布式、具有容錯性應用程序的函數庫和框架。
使用本機格式分發Java應用程序的工具。
用來處理Office格式文檔的函數庫。
游戲開發框架。
用來創建現代圖形用戶界面的函數庫。
與高性能計算有關的資源,包括集合以及很多具體功能的函數庫。
視圖簡化開發的集成開發環境。
用來幫助創建、評估或操作圖形的函數庫。
簡化JSON處理的函數庫。
目前的JVM、JDK實現。
記錄應用程序的日志函數庫。
提供具體統計算法的工具。其算法可從數據中學習。
在客戶端之間進行消息傳遞,確保協議獨立性的工具。
其它資源。
用來專門處理文本的函數庫。
網絡編程函數庫。
處理對象持久化的API。
用來幫助創建PDF文件的資源。
用來創建RESTful 服務的框架。
用于科學計算和分析的函數庫。
文檔索引引擎,用于搜索和分析。
用于處理安全、認證、授權或會話管理的函數庫。
用來高效處理序列化的函數庫。
用來部署應用程序的服務器。
對模板中表達式進行替換的工具。
測試內容從對象到接口,涵蓋性能測試和基準測試工具。
通用工具類函數庫。
用于分析網站內容的函數庫。
用于處理Web應用程序不同層次間通訊的框架。
活躍的討論區。
具有廣泛影響且值得閱讀的Java經典書籍。
可以一邊編程一邊聽的東西。
值得關注的帳號。
值得閱讀的網站。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。