目標
前置技術準備
注冊頁面index.html
注冊后臺程序
前置技術準備
1)html css js jquery基礎 servlet基礎
2)阿里云上傳和下載文件
https://help.aliyun.com/product/31815.html?spm=a2c4g.750001.list.24.542d7b13g1ZPXj
---》https://help.aliyun.com/document_detail/31817.html?spm=a2c4g.11174283.2.2.1ac57da2GaiV3T
阿里云上傳:
https://help.aliyun.com/document_detail/84781.html?spm=a2c4g.11186623.2.22.6bfa2e3cxBIaxh
阿里云下載:https://help.aliyun.com/document_detail/84823.html?spm=a2c4g.11186623.2.7.65d06e84HKPGiG#concept-84823-zh
3)c3p0連接池操作mysql
https://blog.csdn.net/chenpuzhen/article/details/80610044
1)resource下配置數(shù)據(jù)庫連接:c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默認配置蔬蕊,c3p0框架默認加載這段默認配置 -->
<default-config>
<!-- 配置JDBC 四個基本屬性 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl"><![CDATA[jdbc:mysql://127.0.0.1:3306/java4?useUnicode=true&characterEncoding=UTF-8]]></property>
<property name="user">root</property>
<property name="password">root</property>
</default-config>
</c3p0-config>
2)utils下的工具類JDBCUtils
public class JDBCUtils {
// 創(chuàng)建C3P0連接池對象的時候,需要在classpath下讀取C3P0的配置文件
private static final DataSource DATA_SOURCE = new ComboPooledDataSource();
public static DataSource getDataSource(){
return DATA_SOURCE;
}
}
3)簡單測試類
public static void main(String[] args) throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from tb_healthcard where telephone = ?";
HealthCode result = queryRunner.query(sql, new BeanHandler<>(HealthCode.class), "18642046589");
System.out.println(result);
}
編寫注冊頁面index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
<script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="css/index.css"/>
<style>
.container{
display:table;
height:100%;
}
.row{
display: table-cell;
vertical-align: middle;
}
.row-centered {
text-align:center;
}
.col-centered {
display:inline-block;
float:none;
text-align:left;
margin-right:-4px;
} /* 需要在一行的元素 */
.inline-style {
display: inline-block;
}
</style>
</head>
<body class="login">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand nb"><img src="imgs/logo.png" style="width: 258px;height: 36px;padding-top: 10px;"/></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">歡迎使用個人電子碼</a></li>
</ul>
</div>
</nav>
<div class="container login">
<div class="row row-centered">
<div class="well col-md-6 col-centered">
<h2 style="color:#000000;margin-top: 0px;" class="text-center">個人電子碼注冊</h2>
<form class="form-horizontal" action="/healthCode/regist"
method="post" enctype="multipart/form-data" onsubmit="return checkForm();">
<div class="form-group col-sm-12">
<label for="file">個人近期照片:</label>
<input type="file" id="file" name="file">
</div>
<div class="form-group col-sm-12">
<label for="name">姓名:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="請輸入姓名">
</div>
<div class="form-group col-sm-12">
<label for="telephone">手機號碼:</label>
<input type="text" class="form-control" id="telephone" name="telephone" placeholder="請輸入手機號碼" onblur="checkTel()" />
</div>
<div class="form-group col-sm-12" style="display: none" id="telInfo"></div>
<div class="form-group col-sm-12">
<label for="idcard">身份證號碼:</label>
<input type="text" class="form-control" id="idcard" name="idcard" placeholder="請輸入身份證號碼"/>
</div>
<div class="form-group col-sm-12" style="display: none" id="cardInfo"></div>
<div class="form-group col-sm-12">
<label for="location">居住信息:</label>
<input type="text" class="form-control" id="location" name="location" placeholder="請輸入居住信息"/>
</div>
<div class="form-group col-sm-12">
<label for="carNo">車牌號:</label>
<input type="text" class="form-control" id="carNo" name="carNo" placeholder="請輸入車牌號"/>
</div>
<div class="form-group col-sm-12">
<label for="tmpLocation">是否臨時居住點:</label>
<div class="col-sm-12 ">
<div class="radio-inline">
<input type="radio" name="tmpLocation" id="tmpLocation" value="是"/>是
</div>
<div class="radio-inline">
<input type="radio" name="tmpLocation" id="tmpLocation" value="否"/>否
</div>
</div>
</div>
<div class="form-group col-sm-12">
<label for="telephone">是否14天從國外哥谷、省外返回:</label>
<div class="col-sm-9 inline-style">
<div class="radio-inline">
<input type="radio" name="outToIn" value="是"/>是
</div>
<div class="radio-inline">
<input type="radio" name="outToIn" value="否"/>否
</div>
</div>
</div>
<div class="form-group col-sm-12">
<label for="sex">性別:</label>
<div class="col-sm-12">
<div class="radio-inline">
<input type="radio" name="sex" id="sex" value="男"/>男
</div>
<div class="radio-inline">
<input type="radio" name="sex" id="sex" value="女"/>女
</div>
</div>
</div>
<div class="input-group col-sm-12">
<label for="health">身體是否正常:</label>
<div class="col-sm-12">
<div class="radio-inline">
<input type="radio" name="health" id="health" value="是"/>是
</div>
<div class="radio-inline">
<input type="radio" name="health" id="health"value="否"/>否
</div>
</div>
</div>
<div class="form-group col-sm-12" style="padding-top: 10px">
<button type="submit" class="btn btn-primary btn-block">注冊健康碼</button>
<a href="login.html" class="btn btn-block" style="background-color: green; color: white;">我的健康碼</a>
</div>
</form>
</div>
</div>
</div>
</body>
<script type="text/javascript">
function checkTel() {
// 判斷手機號碼是否輸入
var tel = $("#telephone").val();
// 通過正則表達式袁串,判斷手機號碼是否填寫
var reg = /^1[3456789]\d{9}$/;
if( !reg.test(tel)){
$("#telInfo").show().html("<font color='red'>手機號碼不正確</font>");
return false;
}
$.post("/healthCode/checkTel","telephone="+tel,function (resp) {
if( resp == 0 ){ // 0 表示可以用 ; 1 表示已經被注冊
$("#telInfo").hide();
return true ;
}else if( resp == 1){
$("#telInfo").show().html("<font color='red'>手機號碼已注冊</font>");
return false;
}else if( resp == 2 ){
$("#telInfo").show().html("<font color='red'>手機號碼必須填寫</font>");
return false;
}
})
}
// 通過jQuery給頁面的input綁定事件
$(function(){
$("#idcard").blur(function () {
// 處理身份證號碼
var card = $("#idcard").val();
if( card == null || card == "" ){
$("#cardInfo").show().html("<font color='red'>身份證號碼不能為空</font>");
return ;
}
// 訪問后臺
$.post("/healthCode/checkCard","idcard="+card, function (resp) {
if( resp == 0 ){ // 0 表示可以用 呼巷; 1 表示已經被注冊
$("#cardInfo").hide();
}else if( resp == 1){
$("#cardInfo").show().html("<font color='red'>身份證號碼已注冊</font>");
}else if( resp == 2 ){
$("#cardInfo").show().html("<font color='red'>身份證號碼必須填寫</font>");
}
})
})
});
function checkForm() {
return checkTel();
}
</script>
</html>
注冊后臺
注冊驗證###
step 1 驗證身份證合法性
@WebServlet(name = "CheckCardServlet" ,urlPatterns = "/checkCard")
public class CheckCardServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String idcard = request.getParameter("idcard");
if(StringUtils.isBlank(idcard)){
response.getWriter().write("2");
return ;
}
HealthCodeService healthCodeService = new HealthCodeService();
int x = healthCodeService.checkCard(idcard);
if( x == 1 ){
response.getWriter().write("1");
}else{
response.getWriter().write("0");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
2)HealthCodeService
public class HealthCodeService {
private HealthCodeDao healthCodeDao = new HealthCodeDao();
/**
* 檢測身份證號碼是否被注冊
* @param idcard
* @return
*/
public int checkCard(String idcard) {
try{
HealthCode healthCode = this.healthCodeDao.checkCard(idcard);
if(healthCode == null){
return 0;
}
return 1;
}catch (SQLException e){
e.printStackTrace();
}
return 4;
}
}
3)HealthCodeDao
package com.neusoft.dao;
import com.neusoft.pojo.HealthCode;
import com.neusoft.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import java.sql.SQLException;
public class HealthCodeDao {
// 使用DbUitls操作數(shù)據(jù)
private QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource()); /**
* 根據(jù)身份證號碼查詢HealthCode對象,如果查詢到赎瑰,
* 說明身份證號碼已經被注冊王悍,如果查詢不到,說明身份證號碼沒有注冊
* @param idcard
* @return
*/
public HealthCode checkCard(String idcard) throws SQLException {
String sql = "select * from tb_healthcard where idcard = ?";
return queryRunner.query(sql , new BeanHandler<>(HealthCode.class) , idcard);
}
}
測試
step 2 驗證手機號合法性
學生完成
代碼參考
@WebServlet("/checkTel")
public class CheckTelServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String telephone = req.getParameter("telephone");
// 判斷手機號碼是否填寫
if ( StringUtils.isBlank( telephone ) ) {
resp.getWriter().write("2");
return ;
}
HealthCodeService healthCodeService = new HealthCodeService();
int x = healthCodeService.checkTel(telephone);
if( x == 1 ){
resp.getWriter().write("1");
}else{
resp.getWriter().write("0");
}
}
}
/**
* 檢測 手機號碼有沒有被注冊
* @param telephone
* @return
*/
public int checkTel(String telephone) {
try{
HealthCode healthCode = this.healthCodeDao.checkTel(telephone);
if( healthCode == null ){
return 0;
}else{
return 1;
}
}catch (SQLException e){
e.printStackTrace();
}
return 4;
}
/**
* 根據(jù)手機號碼查詢HealthCode對象餐曼,如果能夠查詢压储,說明手機號碼已經被注冊
* @param telephone
* @return
*/
public HealthCode checkTel(String telephone) throws SQLException {
String sql = "select * from tb_healthcard where telephone = ?";
return queryRunner.query(sql , new BeanHandler<>(HealthCode.class) , telephone);
}
驗證通過后的注冊程序
/healthCode/regist
1)service里新增
/**
* 注冊個人健康碼的邏輯
* @param healthCode
* @throws SQLException
*/
public void registHealthInfo(HealthCode healthCode) throws SQLException {
// 默認注冊的時候是綠碼
healthCode.setCardColor("綠碼");
// 注冊時間
healthCode.setCreateTime( new Date() );
// TODO: 手機號碼和身份證號碼是否已經被注冊
this.healthCodeDao.registHealthInfo(healthCode);
}
2)HealthCodeDao里新增
/**
* 用于將HealthCode對象中的數(shù)據(jù)插入到數(shù)據(jù)庫
* @param healthCode
*/
public void registHealthInfo(HealthCode healthCode) throws SQLException {
// 插入數(shù)據(jù)
String sql = "insert into tb_healthcard values(null , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ?)";
Object[] objs = { healthCode.getImgUrl(), healthCode.getTelephone() , healthCode.getIdcard() ,
healthCode.getLocation() , healthCode.getCarNo() , healthCode.getTmpLocation(),
healthCode.getOutToIn() , healthCode.getSex() , healthCode.getHealth(),
healthCode.getCreateTime(), healthCode.getCardColor() , healthCode.getName()};
queryRunner.update(sql , objs);
}
3)RegistServlet編寫
package com.neusoft.servlet;
import com.neusoft.pojo.HealthCode;
import com.neusoft.service.HealthCodeService;
import com.neusoft.utils.OSSUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
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.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@WebServlet("/regist")
public class RegistServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 判斷表單是否支持文件上次
if( !ServletFileUpload.isMultipartContent( req ) ){
resp.setContentType("text/html;charset=utf-8");
// 需要寫日志
resp.getWriter().write("服務器忙,請稍后再試.......");
}
// 集合是為了臨時存儲上傳的數(shù)據(jù)
Map<String , Object> map = new HashMap<>();
// 處理上傳的數(shù)據(jù)
try{
// 創(chuàng)建工廠對象
FileItemFactory factory = new DiskFileItemFactory();
// 創(chuàng)建用于解析request的對象
ServletFileUpload fileUpload = new ServletFileUpload(factory);
// 解析request
List<FileItem> fileItems = fileUpload.parseRequest(req);
// 判斷form表單是否提交了數(shù)據(jù)
if( fileItems != null && fileItems.size() > 0 ){
// 遍歷集合源譬,獲取提交的數(shù)據(jù)
for (FileItem fileItem : fileItems) {
// 判斷 當前遍歷出來的form中的某個input項是否是文件項
if( fileItem.isFormField() ){
// 非文件項
map.put(fileItem.getFieldName() , fileItem.getString("utf-8"));
}else{
// 文件項 ,需要將數(shù)據(jù)上傳的阿里云的oss服務中
String url = OSSUtils.uploadFile(fileItem.getInputStream(), fileItem.getName());
map.put("imgUrl",url);
}
}
// 將頁面提交的數(shù)據(jù)全部封裝到實體類上
HealthCode healthCode = new HealthCode();
// 借助apache的 BeanUtils工具類集惋,快速將map集合中的數(shù)據(jù)封裝到pojo對象上
BeanUtils.populate(healthCode , map); // 底層使用的反射技術
// 將數(shù)據(jù)傳遞給service
HealthCodeService healthCodeService = new HealthCodeService();
healthCodeService.registHealthInfo(healthCode);
// 注冊成功之后,讓瀏覽器跳轉到登陸頁面
resp.sendRedirect( req.getContextPath() + "/login.html" );
}
}catch (Exception e){
e.printStackTrace();
}
}
}
com.neusoft.utils.OSSUtils
public class OSSUtils {
public static String uploadFile(InputStream in , String fileName){
//build(String endpoint, String accessKeyId, String secretAccessKey)
OSS ossClient = new OSSClientBuilder().build(AliYunContant.endpoint, AliYunContant.accessKeyId, AliYunContant.accessKeySecret);
// 獲取到多級目錄
String dirs = DirUtils.getDirs(fileName);
//完整文件名稱
String objectName = AliYunContant.objectName +"/" + dirs + fileName;
//public PutObjectResult putObject(String bucketName, String key, InputStream input)
ossClient.putObject(AliYunContant.bucketName, objectName,in);
ossClient.shutdown();
return "https://qb-img-demo.oss-cn-beijing.aliyuncs.com/"+objectName;
}
}
com.neusoft.pojo.AliYunContant
public class AliYunContant {
/**
* 阿里云服務的訪問路徑
*/
public static final String endpoint = "http://oss-cn-beijing.aliyuncs.com";
/**
* 申請的阿里云的賬號id踩娘,注意保密
*/
public static final String accessKeyId = "LTAI9F6tVv1BYYOy";
/**
* 申請的阿里云的賬號時分配的一個認證的唯一字符串刮刑,建議在實際項目中的時候,
* 不要直接使用主認證字符串养渴,針對阿里云平臺不同的服務雷绢,申請不同的子認證密碼
*/
public static final String accessKeySecret = "vstrLXnfWrOTACv14Qm4kBs8ialluE";
/**
* OSS對象存儲的桶的名稱
*/
public static final String bucketName = "qb-img-demo";
/**
* 創(chuàng)建的桶下,存儲具體的文件的目錄
*/
public static final String objectName = "health";
}
com.neusoft.utils.DirUtils
package com.neusoft.utils;
public class DirUtils {
/**
* 根據(jù)傳遞的文件名理卑,最終通過某個算法計算出多個不同存儲文件的目錄
* @param fileName
* @return
* 101 0101 0100 1010 0101
* & 000 0000 0000 0000 1111
* ----------------------------------
* 000 0000 0000 0000 0101
*/
public static String getDirs(String fileName){
// 通過傳遞的文件名翘紊,計算字符串的哈希值
int hashCode = fileName.hashCode();
// 針對上面的int值,然后按照每4個二進制位為一個單位藐唠,獲取其中的數(shù)字帆疟,作為目錄使用
StringBuilder sb = new StringBuilder();
// 獲取4個數(shù)字,共計組成4層目錄
for( int i = 0 ; i < 4 ; i++ ){
int x = hashCode & 0b1111;
sb.append(x+"/");
// 獲取到最低4個二進制數(shù)位作為某級目錄之后宇立,將原來的數(shù)字右移
hashCode = hashCode >>> 4;
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(getDirs("abcde.txt"));
}
}
login.html
先打印一個簡單的helloworld
測試
查看數(shù)據(jù)庫記錄和阿里云圖片情況踪宠,如果沒問題,即為成功