由于我们学校的hustoj版本久远,业务和视图混在一起,可扩展性较差,正好缺一个账号找回功能,然后我就写了一个另外的web项目挂在了自己的服务器上以解决这个问题。因为mysql中的密码是经过几次加密写进去的,不可以直接用数据库修改,然后我就想到了用htmlunit模拟登陆我自己(管理员),模拟使用changepassword功能,同理使用这个功能核对要找回的账号和写的邮箱(邮箱只有自己知道),然后使用JavaMail对账号的邮箱发送随机的验证码对邮箱进行验证,输入对了就可以进行修改。验证码的写法还比较简单,将验证码获得时间写入数据库(只要设置default update就行了,不用代码处理),每次有人核对成功要获得验证码时,检查该账户是否已经获取过验证码了。如果获取过,取出时间,和当前的时间做一个减法,如果时差大于2分钟就判定验证码失效,删掉原来记录重新写入一个新的,没获取过就直接插入信息,或者获取过但是还在2分钟有效期内,就发出提示信息并不允许再获得验证码。同理核对验证码正确性也要做一个验证码的时效检查,验证码一旦使用过就直接删掉。
效果图:
数据库脚本:
DROP DATABASE server ;
CREATE DATABASE IF NOT EXISTS server DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
use server
create table user(
id varchar(20) primary key not null,
code varchar(20) not null,
mail varchar(30) not null,
time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)engine=innodb default charset=utf8;
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这是一条分界线,就在我前几天准备写这篇博客的时候,我惊奇得发现我把项目代码给删了。。然后从服务器端传回来,反编译一下,一堆报错和乱七八糟的注释。。绝望得我只好重新写了这个项目,正好优化一下,这次我用的
是springboot+mybatis+JavaMail+HtmlUnit,项目写好后测试响应时间大概是1s,多的时候是3.5s,其中有3s是模拟管理员登陆花费的时间。。。没办法优化了,只能以后发现oj的加密方法直接对数据库来操作应该会快很多。
ps:由于服务器运行内存只有1g,经常出现卡死状态qaq。
重写效果图:
核心代码:
项目框架:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wust</groupId>
<artifactId>servlet</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>servlet</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--数据库相关-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--spring操作数据库jpa 用于将数据存入数据库的类和方法的集-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.33</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- JDBC连接池依赖 -->
<dependency><groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- 添加对 mybatis 的依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 添加对 JDBC 的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主类(要标注各种包的扫描情况):
package com.wust.servlet;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
@SpringBootApplication
@ComponentScan("controller")
@ComponentScan("entity")
@ComponentScan("service")
@ComponentScan("conf")
@MapperScan("mapper")
@EnableAutoConfiguration
public class ServletApplication {
public static void main(String[] args) {
SpringApplication.run(ServletApplication.class, args);
}
}
SpringBoot的配置文件,,里面写一些数据库配置相关的信息:
spring.thymeleaf.cache=false
# 设置数据库相关
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/server
spring.datasource.username =root
spring.datasource.password =666666
# 设置 c3p0 数据源
spring.datasource.type=com.mchange.v2.c3p0.ComboPooledDataSource
# 设置 MyBatis mapper 的别名所在的包
mybatis.type-aliases-package=mapper
server.port=80
Mybatis的Mapper类:
package mapper;
import entity.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserMapper{
@Select("select * from user where id = #{id}")
public User findUser(String id);
@Insert("insert into user(id,code,mail,time) values(#{id},#{code},#{mail},default)")
public int insertUser(User user);
@Delete("delete from user where id = #{id}")
public int deleteUser(String id);
}
配置连接池和sqlsession的Bean:
package conf;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import java.beans.PropertyVetoException;
@SpringBootConfiguration
public class DataSourceConfiguration {
@Value("${spring.datasource.driverClassName}")
private String jdbcDriver;
@Value("${spring.datasource.url}")
private String jdbcUrl;
@Value("${spring.datasource.username}")
private String jdbcUser;
@Value("${spring.datasource.password}")
private String jdbcPassword;
@Bean
public ComboPooledDataSource createDataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(jdbcDriver);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUser(jdbcUser);
dataSource.setPassword(jdbcPassword);
// 关闭连接后不自动提交
dataSource.setAutoCommitOnClose(false);
return dataSource;
}
}
User的pojo类,其中重写了equals方法之后会用到:
package entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.persistence.Entity;
import java.util.Date;
@Component
@Entity
public class User {
private String id;
private String code;
private String mail;
private Date time;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof User)) {
return false;
}
User user = (User)o;
return (user.getId().equals(this.id)) && (user.getCode().equals(this.code)) && (user.getMail().equals(this.mail));
}
}
Admin类,主要用于用htmlunit模拟管理员登陆,进行账号邮箱确认和密码修改的模拟:
package service;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.*;
import com.gargoylesoftware.htmlunit.util.Cookie;
import org.springframework.stereotype.Service;
@Service
public class Admin
{
public void ChangePwd(String user_id, String new_pwd) throws java.io.IOException
{
WebClient webclient = new WebClient();
webclient.getOptions().setCssEnabled(false);
webclient.getOptions().setJavaScriptEnabled(false);
webclient.getOptions().setRedirectEnabled(true);
webclient.getCookieManager().setCookiesEnabled(true);
HtmlPage htmlpage = (HtmlPage)webclient.getPage("http://acm.wust.edu.cn/loginpage.php");
HtmlForm form = (HtmlForm)htmlpage.getForms().get(0);
HtmlElement button = (HtmlElement)htmlpage.getElementByName("submit");
HtmlTextInput nameField = (HtmlTextInput)form.getInputByName("user_id");
nameField.setValueAttribute("自己的账号");
HtmlPasswordInput pwdField = (HtmlPasswordInput)form.getInputByName("password");
pwdField.setValueAttribute("自己的密码");
button.click();
java.util.Set<Cookie> cookies = webclient.getCookieManager().getCookies();
java.util.Map<String, String> responseCookies = new java.util.HashMap();
for (Cookie c : cookies) {
responseCookies.put(c.getName(), c.getValue());
}
HtmlPage nextPage = (HtmlPage)webclient.getPage("保密");//之后是分析页面获取按钮模拟修改密码
HtmlForm form1 = (HtmlForm)nextPage.getForms().get(0);
HtmlTextInput name = (HtmlTextInput)form1.getInputByName("user_id");
HtmlTextInput pwd = (HtmlTextInput)form1.getInputByName("passwd");
com.gargoylesoftware.htmlunit.html.HtmlInput btn = (HtmlInput)form1.getInputsByValue("xxxx").get(0);
name.setValueAttribute(user_id);
pwd.setValueAttribute(new_pwd);
String result = nextPage.asXml();
btn.click();
webclient.close();
}
public boolean checkExist(String id, String Mail) throws java.io.IOException
{
WebClient webclient = new WebClient();
webclient.getOptions().setCssEnabled(false);
webclient.getOptions().setJavaScriptEnabled(false);
webclient.getOptions().setRedirectEnabled(true);
webclient.getCookieManager().setCookiesEnabled(true);
HtmlPage htmlpage = (HtmlPage)webclient.getPage("http://acm.wust.edu.cn/loginpage.php");
HtmlForm form = (HtmlForm)htmlpage.getForms().get(0);
HtmlElement button = (HtmlElement)htmlpage.getElementByName("submit");
HtmlTextInput nameField = (HtmlTextInput)form.getInputByName("user_id");
nameField.setValueAttribute("自己的账号");
HtmlPasswordInput pwdField = (HtmlPasswordInput)form.getInputByName("password");
pwdField.setValueAttribute("自己的密码");
button.click();
java.util.Set<Cookie> cookies = webclient.getCookieManager().getCookies();
java.util.Map<String, String> responseCookies = new java.util.HashMap();
for (Cookie c : cookies) {
responseCookies.put(c.getName(), c.getValue());
}
HtmlPage nextPage = (HtmlPage)webclient.getPage("http://acm.wust.edu.cn/userinfo.php?user=" + id);
if (nextPage.getByXPath("/html/body/div[@id='wrapper']/div[@id='main']/center/font[1]").size() == 0)//这里是xpath表达式获取页面元素
{
return false;
}
HtmlElement item = (HtmlElement)nextPage.getByXPath("/html/body/div[@id='wrapper']/div[@id='main']/center/font[1]").get(0);
String xml = item.asXml();
String mail = "";
String regex = "[a-zA-z\\.[0-9]]*@[a-zA-z[0-9]]*\\.com";
java.util.regex.Pattern p = java.util.regex.Pattern.compile(regex);
java.util.regex.Matcher m = p.matcher(xml);
int num = 0;
while (m.find()) {
mail = m.group().toString();
}
webclient.close();
if (Mail.equals(mail))
return true;
return false;
}
}
CodeHandle类主要用于核对数据库里的验证码有效性,以及验证2分钟的有效期:
package service;
import java.util.Date;
import entity.User;
import mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CodeHandle
{
@Autowired
private UserMapper userMapper;
@Autowired
@Transactional
public boolean CheckValid(User user)
{
User user1 = userMapper.findUser(user.getId());
if (user.equals(user1))
{
return true;
}
return false;
}
@Autowired
@Transactional
public boolean CheckRepeat(User user)
{
User user1 = userMapper.findUser(user.getId());
if (user1 == null)
return false;
Date d1 = new Date();
Date d2 = user1.getTime();
if (d1.getTime() - d2.getTime() >= 120000)
{
userMapper.deleteUser(user.getId());
return false;
}
return true;
}
}
Mail类,主要用于发送验证码:
package service;
import com.sun.mail.util.MailSSLSocketFactory;
import entity.User;
import mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
import java.util.Random;
@Service
public class Mail
{
@Autowired
UserMapper userMapper;
@Transactional
public void sendCode(User user)
{
try
{
Properties prop = new Properties();
prop.setProperty("mail.debug", "true");//设置debug信息打印
prop.setProperty("mail.host", "smtp.qq.com");
prop.setProperty("mail.smtp.auth", "true");
prop.setProperty("mail.transport.protocol", "smtp");
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
Session session = Session.getInstance(prop);
Transport ts = session.getTransport();
ts.connect("smtp.qq.com", "qq号", "这里填邮箱里的授权码(没有的要去qq邮箱那设置)");
Message message = createSimpleMail(user, session);
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
@Transactional
public MimeMessage createSimpleMail(User user, Session session) throws Exception
{
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("这里填发件人的邮箱"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getMail()));
message.setSubject("OJ账号找回");
Random rand = new Random();
Integer t = Integer.valueOf(rand.nextInt(90000) + 10000);//生成5位随机数
user.setCode(t.toString());
userMapper.insertUser(user);
message.setContent("本次的修改密码验证码为:" + t + ",2分钟内有效。若非本人操作,请尽快联系WUSTOJ管理员,qq:845723932 ", "text/html;charset=UTF-8");
return message;
}
}
Controller,用于调度service和请求回复:
package controller;
import entity.User;
import mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import service.Admin;
import service.CodeHandle;
import service.Mail;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("/")
public class PageController {
@Autowired
Admin admin;
@Autowired
CodeHandle codeHandle;
@Autowired
Mail mail;
@Autowired
UserMapper userMapper;
@GetMapping("/index")
public String index() {
return "index";
}
@PostMapping("/GetCode")
@ResponseBody
public Map<String,String> GetCode(HttpSession httpSession, User user) throws IOException {
Map<String,String>map=new HashMap<String,String>();
String msg="未知错误";
try {
if(user.getId()==null||user.getMail()==null||(user.getId().equals("")) || (user.getMail().equals("")))
{
msg="账号或邮箱未填!";
}
else if (admin.checkExist(user.getId(), user.getMail())) {
httpSession.setAttribute("uid", user.getId());
httpSession.setAttribute("umail", user.getMail());
if (codeHandle.CheckRepeat(user)) {
msg="你已获得过验证码!";
} else {
mail.sendCode(user);
msg="获取验证码成功!";
}
} else {
msg="输入的账号或邮箱信息有误!";
}
} catch (Exception e) {
e.printStackTrace();
}
map.put("msg",msg);
return map;
}
@PostMapping("/CheckCode")
@ResponseBody
public Map<String,String> CheckCode(HttpSession httpSession,User user, @RequestParam("pwd") String pwd) throws IOException {
Map<String,String>map=new HashMap<String,String>();
if(httpSession.getAttribute("uid")!=null)
{
user.setId((String)httpSession.getAttribute("uid"));
}
if(httpSession.getAttribute("umail")!=null)
{
user.setMail((String)httpSession.getAttribute("umail"));
}
if (user.getId()==null||user.getMail()==null||(user.getId().equals("")) || (user.getMail().equals(""))) {
map.put("msg", "账号和邮箱不能为空!");
}
else if(user.getCode()==null||pwd==null||user.getCode().equals("")||pwd.equals(""))
{
map.put("msg","验证码或密码不能为空");
}
else if (codeHandle.CheckRepeat(user)) {
if (codeHandle.CheckValid(user)) {
try {
admin.ChangePwd(user.getId(), pwd);
map.put("msg", "修改密码成功!");
} catch (Exception e) {
e.printStackTrace();
}
userMapper.deleteUser(user.getId());
} else {
map.put("msg", "输入验证码有误!");
}
} else {
map.put("msg", "验证码过期或没有获得过验证码!");
}
return map;
}
}
最后是自己写的前端页面,用ajax来请求,设置了获得成功后的倒计时,关掉了异步,因为是局部更新,异步没办法呈现alert信息,采用thymeleaf来实现回填:
<!DOCTYPE html>
<html lang = "chi">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=8">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
<meta name="viewport" content="width=device-width, initial-scale=0.5, maximun-scale=1, minimum-scale=1, user-scaleable=no">
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
/*web background*/
.container{
display:table;
height:100%;
width: 300px;
}
</style>
<title>WUSTOJ账号找回</title>
<script type="text/javascript">
$(document).ready(function () {
$('#codeButton').click(function () {
$.ajax({
async: false,
type: "POST",
url:'/GetCode',
dataType: "json",
data:$("#f1").serialize(),
success: function (data) {
if(data.msg!=null)
alert(data.msg);
if('获取验证码成功!'==data.msg)
{
timer(120);
}
},
error: function () {
}
})
})
$("#sub").click(function () {
$.ajax({
async: false,
type: "POST",
url:'/CheckCode',
dataType: "json",
data:$("#f2").serialize(),
success: function (data) {
if(data.msg!=null)
alert(data.msg);
},
error: function () {
}
})
})
})
function timer(time) {
var btn = $("#codeButton");
btn.attr("disabled", true); //按钮禁止点击
btn.html(time <= 0 ? "发送验证码" : ("" + (time--) + "秒后可发送"));
var hander = setInterval(function() {
if (time <= 0) {
clearInterval(hander); //清除倒计时
btn.html("发送验证码");
btn.attr("disabled", false);
return false;
}else {
btn.html("" + (time--) + "秒后可发送");
}
}, 1000);
}
</script>
</head>
<body style="width: 100%">
<div class="panel panel-info center-block" style="width: 500px">
<div class="form-group text-center panel panel-heading">
<h3>WUSTOJ账号找回</h3>
</div>
<div class="container">
<form id="f1" class="form-horizontal" role="form">
<div class="form-group input-group">
<span class="input-group-addon">账号</span>
<input type="text" class="form-control" placeholder="请输入账号" name="id" th:value="${session.uid}"/>
</div>
<div class="form-group input-group">
<span class="input-group-addon ">邮箱</span>
<input type="text" class="form-control" placeholder="请输入邮箱" name="mail" th:value="${session.umail}"/>
</div>
<div class="form-group input-group">
<div>
<button id="codeButton" class="btn btn-success">获得验证码</button>
</div>
</div>
</form>
<form id="f2" class="form-horizontal" role="form">
<div class="form-group input-group">
<span class="input-group-addon">验证码</span>
<input class="form-control" type="text" placeholder="请输入验证码" name="code"/>
</div>
<div class="form-group input-group">
<span class="input-group-addon ">新密码</span>
<input class="form-control" placeholder="请输入新密码" name="pwd"/>
</div>
<div class="form-group input-group">
<div >
<button id="sub" class="btn btn-info">密码修改</button>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
ps:
打包方法:在maven界面,右击package,build一下,target处会打包一个jar包
由于spring boot内置了tomcat,直接用java -jar servlet.jar包就可以部署了
也可以自己写一个shell脚本:
startup.sh(同时写入日志到log.file中):
#!/bin/bash
echo starting
java -jar servlet.jar > log.file 2>&1 &
stop的脚本我写的出错了。。
然后是手动用ps -ef|grep servlet查出id直接kill -9 id来杀的进程。。。
有人知道正确写法么orz
然后restart.sh写法:
#!/bin/bash
echo stop application
source stop.sh
echo start application
source startup.sh
github项目源码(当然是修改过的不会暴露信息版):https://github.com/iunique/IdeaProject/tree/master/servlet
总结:
本次项目复习了springboot搭建java web,thymeleaf,mybatis的使用,然后新学了htmlunit爬虫模拟浏览器操作,javamail发送邮件,以及验证码的实现方法,springboot的服务部署,明明是后台又锻炼了一下基础的前端。。还是很有收获的
----------------------------------------------------------------------------------------------------------------------------------------------------------
10月19日更
今天终于发现了为什么ajax异步请求时出错,在index.html中的timer函数清除倒计时那用在hander定义的时候在内部用了hander,通过chorme单步js查查出了这个错。。还有就是发现之前的明明指定了是post方法最后传的却是get,原因是ajax提交的时候form表单会自动提交,form不写method默认为了get,然后解决方法是把button的type设置成button就不会出错了,还有发现貌似还用不到thymeleaf,直接通过jquery来修改元素值的value或者设置表单不刷新就行了,这样响应速度会快一些,下面是修改过的index.html代码:
<!DOCTYPE html>
<html lang = "chi">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=8">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
<meta name="viewport" content="width=device-width, initial-scale=0.5, maximun-scale=1, minimum-scale=1, user-scaleable=no">
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
/*web background*/
.container{
display:table;
height:100%;
width: 300px;
}
</style>
<title>WUSTOJ账号找回</title>
<script type="text/javascript">
function timer(time) {
var btn = $("#codeButton");
btn.attr("disabled", true); //按钮禁止点击
btn.html(time <= 0 ? "发送验证码" : ("" + (time--) + "秒后可发送"));
var hander = setInterval(function() {
if (time <= 0) {
clearInterval(this); //清除倒计时
btn.html("发送验证码");
btn.attr("disabled", false);
return false;
}else {
btn.html("" + (time--) + "秒后可发送");
}
}, 1000);
}
$(document).ready(function () {
$('#codeButton').click(function () {
$.ajax({
async: true,
type: "POST",
url:'/GetCode',
dataType: "json",
data:$("#f1").serialize(),
success: function (data) {
if(data.msg!=null)
alert(data.msg);
if('获取验证码成功!'==data.msg)
{
timer(120);
$("#i1").val(data.id);
$("#i2").val(data.mail);
}
},
error: function () {
alert("操作异常!");
}
})
})
$("#sub").click(function () {
$.ajax({
async: true,
type: "POST",
url:'/CheckCode',
dataType: "json",
data:$("#f2").serialize(),
success: function (data) {
if(data.msg!=null)
alert(data.msg);
},
error: function () {
alert("操作异常");
}
})
})
})
</script>
</head>
<body style="width: 100%">
<div class="panel panel-info center-block" style="width: 500px">
<div class="form-group text-center panel panel-heading">
<h3>WUSTOJ账号找回</h3>
</div>
<div class="container">
<form id="f1" class="form-horizontal" role="form">
<div class="form-group input-group">
<span class="input-group-addon">账号</span>
<input id="i1"type="text" class="form-control" placeholder="请输入账号" name="id" />
</div>
<div class="form-group input-group">
<span class="input-group-addon ">邮箱</span>
<input id="i2" type="text" class="form-control" placeholder="请输入邮箱" name="mail" />
</div>
<div class="form-group input-group">
<div>
<button id="codeButton" class="btn btn-success" type="button">获得验证码</button>
</div>
</div>
</form>
<form id="f2" class="form-horizontal" role="form">
<div class="form-group input-group">
<span class="input-group-addon">验证码</span>
<input class="form-control" type="text" placeholder="请输入验证码" name="code"/>
</div>
<div class="form-group input-group">
<span class="input-group-addon ">新密码</span>
<input class="form-control" placeholder="请输入新密码" name="pwd"/>
</div>
<div class="form-group input-group">
<div >
<button id="sub" class="btn btn-info" type="button">密码修改</button>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
10月23日更,今天发现项目又挂了,上去看日志发现报的是socket time out,大概是数据库连接超时了,没有设置重连,然后找到了这几篇文章,修改更新了下项目~
https://blog.csdn.net/qq_33792843/article/details/74746416
https://blog.csdn.net/feeltouch/article/details/80470172
还有就是在用htmlunit的时候
webclient.getOptions().setTimeout(0);
表示连接不失效
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
10月24日更,今天去看又挂了,貌似是html的webclient那一直报time out,我直接把admin方法全改成了static方法,去掉了以前bean的方式,暂时还没有挂,希望这次能彻底解决问题