在java poi導(dǎo)入Excel通用工具類示例詳解
前言
本文主要給大家介紹了關(guān)于java poi導(dǎo)入Excel通用工具類的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。
問題引入和分析
提示:如果不想看羅嗦的文章,可以直接到最后點(diǎn)擊源碼下載運(yùn)行即可
最近在做一個(gè)導(dǎo)入Excel的功能,在做之前在百度上面查找“java通用導(dǎo)入Excel工具類”,沒有查到,大多數(shù)都是java通用導(dǎo)出Excel。后來仔細(xì)想想,導(dǎo)出可以利用java的反射,做成通用的,放進(jìn)相應(yīng)的實(shí)體成員變量中,導(dǎo)入為什么不可以呢?也是可以的,不過在做之前我們要解決如下兩個(gè)問題:
1.表格中的列數(shù)和順序要和實(shí)體類中的成員變量個(gè)數(shù)和順序一致。
2.表格中的列的類型要和成員變量的類型一致。
第一個(gè)問題:
列數(shù)一致可以做到,但是我們最后都是要插入數(shù)據(jù)庫的。那么id是必不可少的,或者良好的習(xí)慣可能還有創(chuàng)建時(shí)間,創(chuàng)建人等信息。
所以我想到了兩個(gè)辦法:
1.封裝一個(gè)Vo,只將需要的字段封裝進(jìn)去,并且字段順序和表格列的順序一致,再將vo與實(shí)體類po轉(zhuǎn)化(用PropertyUtil.copy方法);
2.在需要的成員變量上注入自定義注解,并且加入注解的這些字段順序和表格列的順序一致,利用反射得到這些字段。
這里主要利用第二個(gè)方法,因?yàn)閿U(kuò)展性更好
第二個(gè)問題:
獲取表格數(shù)據(jù)的時(shí)候,我們要判斷類型,并取得相應(yīng)值,全部轉(zhuǎn)化為String類型,當(dāng)我們給實(shí)體類賦值的時(shí)候,利用反射獲取需要的成員變量的類型,并賦值。
需求
假設(shè)我們需求的excel如下:

我們可以看做兩部分:
第一部分:
第二行到第11行,為一個(gè)列表數(shù)據(jù),共有字段5個(gè),分別為:學(xué)號(hào),姓名,身份證號(hào)碼,性別,分?jǐn)?shù)
第二部分:
第12行第五列,第12行第六列,共有字段2個(gè),分別為:總計(jì),平均
項(xiàng)目
需要導(dǎo)入的jar包
1.poi的相關(guān)jar包,主要用來處理excel
2.beanutils 利用反射為成員變量賦值
3.commons-lang String判斷非空的方法,可以不用自己判斷
如若maven項(xiàng)目導(dǎo)入下面的jar包
<!-- poi操作excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.8</version>
</dependency>
<!-- beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.3</version>
</dependency>
<!-- commons-lang-->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
非maven項(xiàng)目導(dǎo)入下面的jar(下面例子當(dāng)中用到的jar,有些沒用到,可自行處理)
commons-beanutils-1.8.3.jar commons-lang-2.6.jar commons-logging-1.1.jar dom4j-1.6.1.jar log4j-1.2.13.jar poi-3.8-20120326.jar poi-excelant-3.8-20120326.jar poi-ooxml-3.8-20120326.jar poi-ooxml-schemas-3.8-20120326.jar poi-scratchpad-3.8-20120326.jar stax-api-1.0.1.jar xmlbeans-2.3.0.jar
項(xiàng)目結(jié)構(gòu)

工具類
package com.dao.chu.excel;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
*
* excel讀取工具類
*
* @author daochuwenziyao
* @see [相關(guān)類/方法]
* @since [產(chǎn)品/模塊版本]
*/
public class ImportExeclUtil
{
private static int totalRows = 0;// 總行數(shù)
private static int totalCells = 0;// 總列數(shù)
private static String errorInfo;// 錯(cuò)誤信息
/** 無參構(gòu)造方法 */
public ImportExeclUtil()
{
}
public static int getTotalRows()
{
return totalRows;
}
public static int getTotalCells()
{
return totalCells;
}
public static String getErrorInfo()
{
return errorInfo;
}
/**
*
* 根據(jù)流讀取Excel文件
*
*
* @param inputStream
* @param isExcel2003
* @return
* @see [類、類#方法、類#成員]
*/
public List<List<String>> read(InputStream inputStream, boolean isExcel2003)
throws IOException
{
List<List<String>> dataLst = null;
/** 根據(jù)版本選擇創(chuàng)建Workbook的方式 */
Workbook wb = null;
if (isExcel2003)
{
wb = new HSSFWorkbook(inputStream);
}
else
{
wb = new XSSFWorkbook(inputStream);
}
dataLst = readDate(wb);
return dataLst;
}
/**
*
* 讀取數(shù)據(jù)
*
* @param wb
* @return
* @see [類、類#方法、類#成員]
*/
private List<List<String>> readDate(Workbook wb)
{
List<List<String>> dataLst = new ArrayList<List<String>>();
/** 得到第一個(gè)shell */
Sheet sheet = wb.getSheetAt(0);
/** 得到Excel的行數(shù) */
totalRows = sheet.getPhysicalNumberOfRows();
/** 得到Excel的列數(shù) */
if (totalRows >= 1 && sheet.getRow(0) != null)
{
totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}
/** 循環(huán)Excel的行 */
for (int r = 0; r < totalRows; r++)
{
Row row = sheet.getRow(r);
if (row == null)
{
continue;
}
List<String> rowLst = new ArrayList<String>();
/** 循環(huán)Excel的列 */
for (int c = 0; c < getTotalCells(); c++)
{
Cell cell = row.getCell(c);
String cellValue = "";
if (null != cell)
{
// 以下是判斷數(shù)據(jù)的類型
switch (cell.getCellType())
{
case HSSFCell.CELL_TYPE_NUMERIC: // 數(shù)字
cellValue = cell.getNumericCellValue() + "";
break;
case HSSFCell.CELL_TYPE_STRING: // 字符串
cellValue = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
cellValue = cell.getBooleanCellValue() + "";
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
cellValue = cell.getCellFormula() + "";
break;
case HSSFCell.CELL_TYPE_BLANK: // 空值
cellValue = "";
break;
case HSSFCell.CELL_TYPE_ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知類型";
break;
}
}
rowLst.add(cellValue);
}
/** 保存第r行的第c列 */
dataLst.add(rowLst);
}
return dataLst;
}
/**
*
* 按指定坐標(biāo)讀取實(shí)體數(shù)據(jù)
* <按順序放入帶有注解的實(shí)體成員變量中>
*
* @param wb 工作簿
* @param t 實(shí)體
* @param in 輸入流
* @param integers 指定需要解析的坐標(biāo)
* @return T 相應(yīng)實(shí)體
* @throws IOException
* @throws Exception
* @see [類、類#方法、類#成員]
*/
@SuppressWarnings("unused")
public static <T> T readDateT(Workbook wb, T t, InputStream in, Integer[]... integers)
throws IOException, Exception
{
// 獲取該工作表中的第一個(gè)工作表
Sheet sheet = wb.getSheetAt(0);
// 成員變量的值
Object entityMemberValue = "";
// 所有成員變量
Field[] fields = t.getClass().getDeclaredFields();
// 列開始下標(biāo)
int startCell = 0;
/** 循環(huán)出需要的成員 */
for (int f = 0; f < fields.length; f++)
{
fields[f].setAccessible(true);
String fieldName = fields[f].getName();
boolean fieldHasAnno = fields[f].isAnnotationPresent(IsNeeded.class);
// 有注解
if (fieldHasAnno)
{
IsNeeded annotation = fields[f].getAnnotation(IsNeeded.class);
boolean isNeeded = annotation.isNeeded();
// Excel需要賦值的列
if (isNeeded)
{
// 獲取行和列
int x = integers[startCell][0] - 1;
int y = integers[startCell][1] - 1;
Row row = sheet.getRow(x);
Cell cell = row.getCell(y);
if (row == null)
{
continue;
}
// Excel中解析的值
String cellValue = getCellValue(cell);
// 需要賦給成員變量的值
entityMemberValue = getEntityMemberValue(entityMemberValue, fields, f, cellValue);
// 賦值
PropertyUtils.setProperty(t, fieldName, entityMemberValue);
// 列的下標(biāo)加1
startCell++;
}
}
}
return t;
}
/**
*
* 讀取列表數(shù)據(jù)
* <按順序放入帶有注解的實(shí)體成員變量中>
*
* @param wb 工作簿
* @param t 實(shí)體
* @param beginLine 開始行數(shù)
* @param totalcut 結(jié)束行數(shù)減去相應(yīng)行數(shù)
* @return List<T> 實(shí)體列表
* @throws Exception
* @see [類、類#方法、類#成員]
*/
@SuppressWarnings("unchecked")
public static <T> List<T> readDateListT(Workbook wb, T t, int beginLine, int totalcut)
throws Exception
{
List<T> listt = new ArrayList<T>();
/** 得到第一個(gè)shell */
Sheet sheet = wb.getSheetAt(0);
/** 得到Excel的行數(shù) */
totalRows = sheet.getPhysicalNumberOfRows();
/** 得到Excel的列數(shù) */
if (totalRows >= 1 && sheet.getRow(0) != null)
{
totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}
/** 循環(huán)Excel的行 */
for (int r = beginLine - 1; r < totalRows - totalcut; r++)
{
Object newInstance = t.getClass().newInstance();
Row row = sheet.getRow(r);
if (row == null)
{
continue;
}
// 成員變量的值
Object entityMemberValue = "";
// 所有成員變量
Field[] fields = t.getClass().getDeclaredFields();
// 列開始下標(biāo)
int startCell = 0;
for (int f = 0; f < fields.length; f++)
{
fields[f].setAccessible(true);
String fieldName = fields[f].getName();
boolean fieldHasAnno = fields[f].isAnnotationPresent(IsNeeded.class);
// 有注解
if (fieldHasAnno)
{
IsNeeded annotation = fields[f].getAnnotation(IsNeeded.class);
boolean isNeeded = annotation.isNeeded();
// Excel需要賦值的列
if (isNeeded)
{
Cell cell = row.getCell(startCell);
String cellValue = getCellValue(cell);
entityMemberValue = getEntityMemberValue(entityMemberValue, fields, f, cellValue);
// 賦值
PropertyUtils.setProperty(newInstance, fieldName, entityMemberValue);
// 列的下標(biāo)加1
startCell++;
}
}
}
listt.add((T)newInstance);
}
return listt;
}
/**
*
* 根據(jù)Excel表格中的數(shù)據(jù)判斷類型得到值
*
* @param cell
* @return
* @see [類、類#方法、類#成員]
*/
private static String getCellValue(Cell cell)
{
String cellValue = "";
if (null != cell)
{
// 以下是判斷數(shù)據(jù)的類型
switch (cell.getCellType())
{
case HSSFCell.CELL_TYPE_NUMERIC: // 數(shù)字
if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell))
{
Date theDate = cell.getDateCellValue();
SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd");
cellValue = dff.format(theDate);
}
else
{
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(cell.getNumericCellValue());
}
break;
case HSSFCell.CELL_TYPE_STRING: // 字符串
cellValue = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
cellValue = cell.getBooleanCellValue() + "";
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
cellValue = cell.getCellFormula() + "";
break;
case HSSFCell.CELL_TYPE_BLANK: // 空值
cellValue = "";
break;
case HSSFCell.CELL_TYPE_ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知類型";
break;
}
}
return cellValue;
}
/**
*
* 根據(jù)實(shí)體成員變量的類型得到成員變量的值
*
* @param realValue
* @param fields
* @param f
* @param cellValue
* @return
* @see [類、類#方法、類#成員]
*/
private static Object getEntityMemberValue(Object realValue, Field[] fields, int f, String cellValue)
{
String type = fields[f].getType().getName();
switch (type)
{
case "char":
case "java.lang.Character":
case "java.lang.String":
realValue = cellValue;
break;
case "java.util.Date":
realValue = StringUtils.isBlank(cellValue) ? null : DateUtil.strToDate(cellValue, DateUtil.YYYY_MM_DD);
break;
case "java.lang.Integer":
realValue = StringUtils.isBlank(cellValue) ? null : Integer.valueOf(cellValue);
break;
case "int":
case "float":
case "double":
case "java.lang.Double":
case "java.lang.Float":
case "java.lang.Long":
case "java.lang.Short":
case "java.math.BigDecimal":
realValue = StringUtils.isBlank(cellValue) ? null : new BigDecimal(cellValue);
break;
default:
break;
}
return realValue;
}
/**
*
* 根據(jù)路徑或文件名選擇Excel版本
*
*
* @param filePathOrName
* @param in
* @return
* @throws IOException
* @see [類、類#方法、類#成員]
*/
public static Workbook chooseWorkbook(String filePathOrName, InputStream in)
throws IOException
{
/** 根據(jù)版本選擇創(chuàng)建Workbook的方式 */
Workbook wb = null;
boolean isExcel2003 = ExcelVersionUtil.isExcel2003(filePathOrName);
if (isExcel2003)
{
wb = new HSSFWorkbook(in);
}
else
{
wb = new XSSFWorkbook(in);
}
return wb;
}
static class ExcelVersionUtil
{
/**
*
* 是否是2003的excel,返回true是2003
*
*
* @param filePath
* @return
* @see [類、類#方法、類#成員]
*/
public static boolean isExcel2003(String filePath)
{
return filePath.matches("^.+\\.(?i)(xls)$");
}
/**
*
* 是否是2007的excel,返回true是2007
*
*
* @param filePath
* @return
* @see [類、類#方法、類#成員]
*/
public static boolean isExcel2007(String filePath)
{
return filePath.matches("^.+\\.(?i)(xlsx)$");
}
}
public static class DateUtil
{
// ======================日期格式化常量=====================//
public static final String YYYY_MM_DDHHMMSS = "yyyy-MM-dd HH:mm:ss";
public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static final String YYYY_MM = "yyyy-MM";
public static final String YYYY = "yyyy";
public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static final String YYYYMMDD = "yyyyMMdd";
public static final String YYYYMM = "yyyyMM";
public static final String YYYYMMDDHHMMSS_1 = "yyyy/MM/dd HH:mm:ss";
public static final String YYYY_MM_DD_1 = "yyyy/MM/dd";
public static final String YYYY_MM_1 = "yyyy/MM";
/**
*
* 自定義取值,Date類型轉(zhuǎn)為String類型
*
* @param date 日期
* @param pattern 格式化常量
* @return
* @see [類、類#方法、類#成員]
*/
public static String dateToStr(Date date, String pattern)
{
SimpleDateFormat format = null;
if (null == date)
return null;
format = new SimpleDateFormat(pattern, Locale.getDefault());
return format.format(date);
}
/**
* 將字符串轉(zhuǎn)換成Date類型的時(shí)間
* <hr>
*
* @param s 日期類型的字符串<br>
* datePattern :YYYY_MM_DD<br>
* @return java.util.Date
*/
public static Date strToDate(String s, String pattern)
{
if (s == null)
{
return null;
}
Date date = null;
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
try
{
date = sdf.parse(s);
}
catch (ParseException e)
{
e.printStackTrace();
}
return date;
}
}
}
自定義注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* 是否需要從解析excel賦值
* @author daochuwenziyao
* @see [相關(guān)類/方法]
* @since [產(chǎn)品/模塊版本]
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.FIELD})
public @interface IsNeeded
{
/**
* 是否需要從解析excel賦值
* @return
* true:需要 false:不需要
* @see [類、類#方法、類#成員]
*/
boolean isNeeded() default true;
}
學(xué)生基本信息
import java.math.BigDecimal;
/**
*
* 學(xué)生基本信息
* @author daochuwenziyao
* @see [相關(guān)類/方法]
* @since [產(chǎn)品/模塊版本]
*/
public class StudentBaseInfo
{
private Integer id;
@IsNeeded
private String no;
@IsNeeded
private String name;
@IsNeeded
private String idnum;
@IsNeeded
private String sex;
@IsNeeded
private BigDecimal grade;
@Override
public String toString()
{
return "StudentBaseInfo [id=" + id + ", no=" + no + ", name=" + name + ", idnum=" + idnum + ", sex=" + sex
+ ", grade=" + grade + "]";
}
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public String getNo()
{
return no;
}
public void setNo(String no)
{
this.no = no;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getIdnum()
{
return idnum;
}
public void setIdnum(String idnum)
{
this.idnum = idnum;
}
public BigDecimal getGrade()
{
return grade;
}
public void setGrade(BigDecimal grade)
{
this.grade = grade;
}
}
學(xué)生統(tǒng)計(jì)信息
/**
*
* 學(xué)生統(tǒng)計(jì)信息
* @author daochuwenziyao
* @see [相關(guān)類/方法]
* @since [產(chǎn)品/模塊版本]
*/
public class StudentStatistics
{
private Integer id;
@IsNeeded
private BigDecimal totalGrade;
@IsNeeded
private BigDecimal avgGrade;
@Override
public String toString()
{
return "StudentStatistics [id=" + id + ", totalGrade=" + totalGrade + ", avgGrade=" + avgGrade + "]";
}
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id = id;
}
public BigDecimal getTotalGrade()
{
return totalGrade;
}
public void setTotalGrade(BigDecimal totalGrade)
{
this.totalGrade = totalGrade;
}
public BigDecimal getAvgGrade()
{
return avgGrade;
}
public void setAvgGrade(BigDecimal avgGrade)
{
this.avgGrade = avgGrade;
}
}
測試類
package com.dao.chu.excel;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.poi.ss.usermodel.Workbook;
public class TestImportExcel
{
public static void main(String[] args) throws IOException, Exception
{
String fileName="student.xlsx";
InputStream in = new FileInputStream(new File("excelfile\\student.xlsx"));
Workbook wb = ImportExeclUtil.chooseWorkbook(fileName, in);
StudentStatistics studentStatistics = new StudentStatistics();
//讀取一個(gè)對(duì)象的信息
StudentStatistics readDateT =
ImportExeclUtil.readDateT(wb, studentStatistics, in, new Integer[] {12, 5}, new Integer[] {13, 5});
System.out.println(readDateT);
//讀取對(duì)象列表的信息
StudentBaseInfo studentBaseInfo = new StudentBaseInfo();
//第二行開始,到倒數(shù)第三行結(jié)束(總數(shù)減去兩行)
List<StudentBaseInfo> readDateListT = ImportExeclUtil.readDateListT(wb, studentBaseInfo, 2, 2);
System.out.println(readDateListT);
}
}
輸出結(jié)果
StudentStatistics [id=null, totalGrade=845, avgGrade=84] [StudentBaseInfo [id=null, no=2012240001, name=張三1, idnum=233314199009062304, sex=男, grade=80], StudentBaseInfo [id=null, no=2012240002, name=張三2, idnum=233314199009062304, sex=男, grade=81], StudentBaseInfo [id=null, no=2012240003, name=張三3, idnum=233314199009062304, sex=男, grade=82], StudentBaseInfo [id=null, no=2012240004, name=張三4, idnum=233314199009062304, sex=男, grade=83], StudentBaseInfo [id=null, no=2012240005, name=張三5, idnum=233314199009062304, sex=男, grade=84], StudentBaseInfo [id=null, no=2012240006, name=張三6, idnum=233314199009062304, sex=男, grade=85], StudentBaseInfo [id=null, no=2012240007, name=張三7, idnum=233314199009062304, sex=男, grade=86], StudentBaseInfo [id=null, no=2012240008, name=張三8, idnum=233314199009062304, sex=男, grade=87], StudentBaseInfo [id=null, no=2012240009, name=張三9, idnum=233314199009062304, sex=男, grade=88], StudentBaseInfo [id=null, no=2012240010, name=張三10, idnum=233314199009062304, sex=男, grade=89]]
源碼下載
源碼分享給大家,上面提到的都在這里,由于很多的數(shù)據(jù)類型沒有試驗(yàn)到,可能會(huì)有些類型有問題,所以希望大家如果遇到問題回復(fù)我,我會(huì)將其完善。
源碼下載:http://xiazai.jb51.net/201709/yuanma/ImportExcelUtil(jb51.net).rar
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- JAVA使用POI獲取Excel的列數(shù)與行數(shù)
- java使用poi讀取ppt文件和poi讀取excel、word示例
- java使用poi讀取excel內(nèi)容方法實(shí)例
- Java利用POI讀取、寫入Excel的方法指南
- Java利用POI實(shí)現(xiàn)導(dǎo)入導(dǎo)出Excel表格示例代碼
- Java 使用poi把數(shù)據(jù)庫中數(shù)據(jù)導(dǎo)入Excel的解決方法
- java poi讀取excel操作示例(2個(gè)代碼)
- java的poi技術(shù)讀取和導(dǎo)入Excel實(shí)例
- Java 使用POI生成帶聯(lián)動(dòng)下拉框的excel表格實(shí)例代碼
- Java中利用POI優(yōu)雅的導(dǎo)出Excel文件詳解
相關(guān)文章
SpringBoot+Security 發(fā)送短信驗(yàn)證碼的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot+Security 發(fā)送短信驗(yàn)證碼的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
詳解Java中的線程讓步y(tǒng)ield()與線程休眠sleep()方法
Java中的線程讓步會(huì)讓線程讓出優(yōu)先級(jí),而休眠則會(huì)讓線程進(jìn)入阻塞狀態(tài)等待被喚醒,這里我們對(duì)比線程等待的wait()方法,來詳解Java中的線程讓步y(tǒng)ield()與線程休眠sleep()方法2016-07-07
Struts2學(xué)習(xí)筆記(6)-簡單的數(shù)據(jù)校驗(yàn)
這篇文章主要介紹Struts2中的數(shù)據(jù)校驗(yàn),通過一個(gè)簡單的例子來說明,希望能給大家做一個(gè)參考。2016-06-06
java編程中實(shí)現(xiàn)調(diào)用js方法分析
這篇文章主要介紹了java編程中實(shí)現(xiàn)調(diào)用js方法,結(jié)合具體實(shí)例形式較為詳細(xì)的分析了java編程中調(diào)用js方法的常用操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-09-09
springboot+vue實(shí)現(xiàn)Token自動(dòng)續(xù)期(雙Token方案)
雙Token方案通過訪問令牌和刷新令牌提高用戶登錄安全性和體驗(yàn),訪問令牌有效期短,包含用戶信息,用于請(qǐng)求校驗(yàn),本文就來介紹一下springboot+vue實(shí)現(xiàn)Token自動(dòng)續(xù)期(雙Token方案),感興趣的可以了解一下2024-10-10
關(guān)于spring版本與JDK版本不兼容的問題及解決方法
這篇文章主要介紹了關(guān)于spring版本與JDK版本不兼容的問題,本文給大家?guī)砹私鉀Q方法,需要的朋友可以參考下2018-11-11

