图形验证码是验证码的一种。验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式。
主要包括三部分
(1)图形验证码的生成
CheckCodeServlet
package com.Servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class CheckCodeServlet
*/
@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckCodeServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("image/jpeg");
HttpSession session = request.getSession();
int width = 60;
int height = 20;
//设置浏览器不要缓存此图片
response.setHeader("Pragma","No-cache");
response.setDateHeader("Expires",0);
//创建内存图像并获取其图形上下文
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
//产生随机验证码
//定义验证码的字符表
String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] rands = new char[4];
for(int i = 0;i < 4; ++i){
int rand = (int)(Math.random() * 36);
rands[i] = chars.charAt(rand);
}
//产生图像
//画背景图
g.setColor(new Color(0xDCDCDC));
g.fillRect(0,0,width,height);
//随机产生120个干扰点
for(int i = 0;i < 120;++ i){
int x = (int)(Math.random() * width);
int y = (int)(Math.random() * height);
int red = (int)(Math.random() * 255);
int green = (int)(Math.random() * 255);
int blue = (int)(Math.random() * 255);
g.setColor(new Color(red,green,blue));
g.drawOval(x,y,1,0);
}
g.setColor(Color.BLACK);
g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));
//在不同的高度上输入验证码的不同字符
g.drawString("" + rands[0],1,17);
g.drawString("" + rands[1],16,15);
g.drawString("" + rands[2],31,18);
g.drawString("" + rands[3],46,16);
g.dispose();
//将验证码输出到客户端
ServletOutputStream sos = response.getOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image,"JPEG",baos);
byte[] buffer = baos.toByteArray();
response.setContentLength(buffer.length);
sos.write(buffer);
baos.close();
sos.close();
//将验证码放到session中
session.setAttribute("checkCode",new String(rands));
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
在页面上显示出验证码
<img border="0" src="checkCodeServlet"/>
QRCode.js:使用 JavaScript 生成二维码
下载
什么是 QRCode.js?
QRCode.js 是一个用于生成二维码的 JavaScript 库。主要是通过获取 DOM 的标签,再通过 HTML5 Canvas 绘制而成,不依赖任何库。
导入
<script type="text/javascript" src="js/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="js/qrcode.min.js"></script>
基本用法
<div id="qrcode"></div>
<script type="text/javascript">
new QRCode(document.getElementById("qrcode"), "http://www.runoob.com"); // 设置要生成二维码的链接
</script>
或者使用一些可选参数设置:
var qrcode = new QRCode("test", {
text: "http://www.runoob.com",
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
同样我们可以使用以下方法:
qrcode.clear(); // 清除代码
qrcode.makeCode("http://www.w3cschool.cc"); // 生成另外一个二维码
示例
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<script type="text/javascript" src="js/jquery-3.5.1.min.js">script>
<script type="text/javascript" src="js/qrcode.min.js">script>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>
<input id="text" type="text" value="http://www.runoob.com"
style="width: 80%" />
<br />
<div id="qrcode" style="width: 100px; height: 100px; margin-top: 15px;">div>
<script type="text/javascript">
var qrcode = new QRCode(document.getElementById("qrcode"), {
width : 100,
height : 100
});
function makeCode() {
var elText = document.getElementById("text");
if (!elText.value) {
alert("Input a text");
elText.focus();
return;
}
qrcode.makeCode(elText.value);
}
makeCode();
$("#text").on("blur", function() {
makeCode();
}).on("keydown", function(e) {
if (e.keyCode == 13) {
makeCode();
}
});
script>
body>
html>
CKEditor官网下载js插件
将下载的zip包解压后 放入WebContent下
引入CKEditor的js文件
<script src="ckeditor/ckeditor.js"></script>
页面中使用CKEditor
<!--在需要使用编辑器的地方插入textarea标签 -->
描述:<textarea name="description" id="description"/></textarea>
<!--将相应的控件替换成编辑器代码 -->
<script type="text/javascript">
window.onload = function()
{
CKEDITOR.replace( 'description');
};
</script>
具体示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>title>
<script src="ckeditor/ckeditor.js">script>
<script type="text/javascript">
window.onload = function() {
CKEDITOR.replace('description',{
filebrowserImageUploadUrl: '../../fileUpload?type=image',// 图片上传组件路径
filebrowserFlashUploadUrl: '../../fileUpload?type=flash' // Flash上传组件路径
});
};
script>
head>
<body>
<form method="post" action="job/add">
招聘岗位:<input type="text" name="position" id="position" /> 招聘人数:<input
type="text" name="quantity" id="quantity" /> 学历要求:<input type="text"
name="education" id="education" /> 薪资:<input type="text"
name="salary" id="salary" /> 联系人:<input type="text" name="contact"
id="contact" /> 联系电话:<input type="text" name="telephone"
id="telephone" /> 描述:
<textarea name="description" id="description" />textarea>
<input type="submit" />
form>
body>
html>
test2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<script type="text/javascript" src="ckeditor/ckeditor.js">script>
<html>
<head>
<title>在线编辑器CKeditor演示title>
head>
<body>
<h3>在线编辑器CKeditor演示h3>
<form action="text1.jsp" method="post" onsubmit="return checkEditor();">
<textarea cols="80" id="mckeditor" name="mckeditor" rows="10">
欢迎使用CKeditor在线编辑器!
textarea>
<script type="text/javascript">
CKEDITOR.replace('mckeditor', {
filebrowserImageUploadUrl: '../../fileUpload?type=image',// 图片上传组件路径
filebrowserFlashUploadUrl: '../../fileUpload?type=flash' // Flash上传组件路径
});
script>
<input type="submit" name="submit" value="提交"/>
form>
<script type="text/javascript">
//编辑器内容检查
function checkEditor() {
//通过javascript 代码读取编辑器中的内容
var editor_data = CKEDITOR.instances.mckeditor.getData();
if (editor_data == "") {
alert("编辑器内容不能为空,请输入具体内容然后再提交!");
return false;
} else {
return true;
}
}
script>
body>
html>
test1.jsp
<%@ page import="java.io.File" %>
<%@ page import="java.io.FileOutputStream" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>在线编辑器CKeditor演示title>
head>
<body>
<h3>在线编辑器CKeditor演示h3>
<hr>
<%
request.setCharacterEncoding("utf-8");
String context = request.getParameter("mckeditor");
String realPath = application.getRealPath("/upload").replaceAll("\\\\", "/");
String fileName = String.valueOf(System.currentTimeMillis()) + ".html";
File file = new File(realPath, fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(context.getBytes());
fos.flush();
fos.close();
out.println("表单内容已写入文件:" + realPath + "/" + fileName + "<hr>");
out.println(context);
%>
body>
html>
要实现Web开发的上传功能,通常需要完成两步操作:一是在Web页面中添加上传输入项;二是在Servlet中读取上传文件的数据,并保存到本地硬盘中。
上传大多数情况是通过表单的形式提交给服务器,使用标签。
使用标签需要注意以下两点:
1.必须设置name属性,不然浏览器不会发送上传文件的数据。
2.必须将method属性设置为post,ectype属性设置为“multipart/form-data”类型。
由于在Servlet直接读取上传数据,并且解析出相应文件数据是一项非常麻烦的工作。为了方便处理上传数据,Apache组织提供了一个开源组件Commons-FileUpload。该组件可以将“multipart/form-data”类型请求的各种表单域解析出来,并实现一个或多个文件上传,同时也可以限制上传文件的大小等内容。其性能十分优异,使用极其简单。
所需jar包
这个小组件,它会帮我们解析request中的上传数据,解析后的结果是一个表单项数据封装到一个FileItem对象中。我们只需要调用FileItem的方法即可!
上传三步
1). 创建工厂:DiskFileItemFactory factory = new DiskFileItemFactory();
2). 创建解析器:ServletFileUpload sfu = new ServletFileUpload(factory);
3). 使用解析器来解析request,得到FileItem集合:List fileItemList = sfu.parseRequest(request);
FileItem的API
boolean isFormField():是否为普通表单项!返回true为普通表单项,如果为false即文件表单项!
String getFieldName():返回当前表单项的名称;
String getString(String charset):返回表单项的值;
String getName():返回上传的文件名称
long getSize():返回上传文件的字节数
InputStream getInputStream():返回上传文件对应的输入流
void write(File destFile):把上传的文件内容保存到指定的文件中。
String getContentType();
创建上传页面upload.html
:
<html>
<head lang="en">
<meta charset="UTF-8">
<title>文件上传title>
head>
<body>
<form action="UploadServlet" method="post" enctype="multipart/form-data">
<table width="600">
<tr>
<td>上传者td>
<td><input type="text" name="name"/>td>
tr>
<tr>
<td>上传文件td>
<td><input type="file" name="myfile"/>td>
tr>
<tr>
<td colspan="2"><input type="submit" value="上传"/>td>
tr>
table>
form>
body>
html>
创建UploadServlet:
package com.Servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.UUID;
/**
* Created by lc on 2018/8/24.
*/
@WebServlet(name = "UploadServlet",urlPatterns = "/UploadServlet")
public class UploadServlet extends HttpServlet {
/**
* @Fields serialVersionUID : TODO(用一句话描述这个变量表示什么)
*/
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try{
response.setContentType("text/html;charset=utf-8");
// 创建DiskFileItemFactory工厂对象
DiskFileItemFactory factory=new DiskFileItemFactory();
// 设置文件缓存目录,如果该文件夹不存在则创建一个
File f=new File("D:\\TempFolder");
if (!f.exists()){
f.mkdirs();
}
factory.setRepository(f);
// 创建ServletFileUpload对象
ServletFileUpload fileUpload=new ServletFileUpload(factory);
// 设置字符编码
fileUpload.setHeaderEncoding("utf-8");
// 解析request,将form表单的各个字段封装为FileItem对象
List<FileItem> fileItems = fileUpload.parseRequest(request);
// 获取字符流
PrintWriter writer=response.getWriter();
// 遍历List集合
for (FileItem fileItem:fileItems) {
// 判断是否为普通字段
if (fileItem.isFormField()){
// 获取字段名称
String name = fileItem.getFieldName();
if(name.equals("name")){
// 如果字段值不为空
if (!fileItem.getString().equals("")){
String value=fileItem.getString("utf-8");
writer.print("上传者:"+value+"
");
}
}
}
else {
//获取上传的文件名
String filename=fileItem.getName();
// 处理上传文件
if(filename!=null&&filename!=""){
writer.print("上传的文件名称是:"+filename+"
");
// 保持文件名唯一
filename= UUID.randomUUID().toString()+"_"+filename;
String webpath="/upload/";
// 创建文件路径
String filepath=getServletContext().getRealPath(webpath+filename);
//创建File对象
File file=new File(filepath);
//创建文件夹
file.getParentFile().mkdirs();
//创建文件
file.createNewFile();
//获取上传文件流
InputStream in=fileItem.getInputStream();
// 使用 FileOutputStream打开服务器端的上传文件
FileOutputStream out=new FileOutputStream(file);
// 流的对拷
byte[] bytes=new byte[1024];//每次读取一个字节
int len;
// 开始读取上传文件的字节,并将其输出到服务器端的上传文件输出流中
while ((len=in.read(bytes))>0)
out.write(bytes,0,len);
in.close();
out.close();
fileItem.delete();
writer.print("文件上传成功!");
}
}
}
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
至此,文件上传功能就已经实现了。此时,进入项目发布目录,就可以看到上传的文件了,如下图
下载就是向客户端响应字节数据!
原来我们响应的都是html的字符数据!
把一个文件变成字节数组,使用response.getOutputStream()来响应给浏览器!!!
创建下载页面download.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<a href="DownloadServlet?filename=1.jpg">文件下载</a>
</body>
</html>
创建DownloadServlet
package com.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by lc on 2018/8/24.
*/
@WebServlet(name = "DownloadServlet",urlPatterns = "/DownloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取文件名
String filename = request.getParameter("filename");
//文件所在的文件夹
String folder="/download/";
//通知浏览器以下载的方式打开
response.addHeader("Content-Type","application/octet-stream");
response.addHeader("Content-Disposition","attachment;filename="+filename);
//通过文件输入流读取文件
InputStream in=getServletContext().getResourceAsStream(folder+filename);
OutputStream out=response.getOutputStream();
byte[] bytes=new byte[1024];
int len=0;
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
}
}
}
3.在项目发布目录,创建download文件夹,并且在文件夹里放置一个名为1.jpg的文件
运行截图:
参考
用eclipse 建立 Maven java项目 参考
导入pom文件相关jar
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>3.11version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.11version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxml-schemasartifactId>
<version>3.11version>
dependency>
HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
public class App
{
public static void main( String[] args ) throws Exception
{
// System.out.println( "Hello World!" );
test();
}
/**
* 测试POI框架读取Eexel文件
*/
public static void test() throws Exception {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\24278\\Desktop\\test.xlsx");
// HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
// XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
//1.读取Excel文档对象
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(fileInputStream);
//2.获取要解析的表格(第一个表格)
XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
//获得最后一行的行号
int lastRowNum = sheet.getLastRowNum();
for (int i = 0; i <= lastRowNum; i++) {//遍历每一行
//3.获得要解析的行
XSSFRow row = sheet.getRow(i);
//4.获得每个单元格中的内容(String)
row.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
String stringCellValue0 = row.getCell(0).getStringCellValue();
String stringCellValue1 = row.getCell(1).getStringCellValue();
String stringCellValue2 = row.getCell(2).getStringCellValue();
String stringCellValue3 = row.getCell(3).getStringCellValue();
System.out.println(stringCellValue0 + "--" + stringCellValue1 + "--" + stringCellValue2 + "--" + stringCellValue3);
}
}
}
Cannot get a text value from a numeric cell
解决办法:在getStringCellValue()之前,需要set一下cell的type。
也就是在读取数据之前需要setCellType(Cell.CELL_TYPE_STRING);把NUMERICI的类型转换为STRING就不会有错误了。
测试导入Excel数据
public class App
{
public static void main( String[] args ) throws Exception
{
// System.out.println( "Hello World!" );
test2();
}
/**
* POI导入数据到Excel
*/
public static void test2() throws Exception {
//创建XSSFWorkbook对象(excel的文档对象)
Workbook wb = new XSSFWorkbook();
//建立新的sheet对象(excel的表单)
Sheet sheet=wb.createSheet("OnePage");
//在sheet里创建第一行,参数为行索引(excel的行),可以是0~65535之间的任何一个
Row row1=sheet.createRow(0);
//创建单元格(excel的单元格,参数为列索引,可以是0~255之间的任何一个
Cell cell=row1.createCell(0);
//设置单元格内容
cell.setCellValue("基本信息表");
//合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
sheet.addMergedRegion(new CellRangeAddress(0,0,0,6));
//在sheet里创建第二行
Row row2=sheet.createRow(1);
//创建单元格并设置单元格内容
row2.createCell(0).setCellValue("ID");
row2.createCell(1).setCellValue("更新时间");
row2.createCell(2).setCellValue("求职状态");
row2.createCell(3).setCellValue("性别");
row2.createCell(4).setCellValue("年龄");
row2.createCell(5).setCellValue("生日");
row2.createCell(6).setCellValue("地址");
row2.createCell(7).setCellValue("工作经验");
row2.createCell(8).setCellValue("项目经验");
row2.createCell(9).setCellValue("自我评价");
//第2行开始写入5行数据
for (int i = 2; i < 5; i++) {
Row row3=sheet.createRow(i);
row3.createCell(0).setCellValue("1");
row3.createCell(1).setCellValue("2020");
row3.createCell(2).setCellValue("五");
row3.createCell(3).setCellValue("男");
}
FileOutputStream output=new FileOutputStream("C:\\Users\\24278\\Desktop\\test.xlsx");
wb.write(output);//写入磁盘
output.close();
}
}