侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册

技术  /  管理员 发布于 9年前   609

最近在仿造一个书城的网站: http://www.yousuu.com ,UI直接拿来用,前端后端自己写,目前大部分功能已经实现,

就把具体的 登录注册功能 拿来分享一下。PS:又写登录注册会不会被人喷啊=。=

一、开发环境的部署

程序结构:

BootStrap+Ajax+Struts2+Hibernate+MySql

仅供参考:能实现相关功能即可

操作系统:ubuntu 14.10

前端框架:BootStrap   注:此框架只是为了实现用户界面,和具体功能无关

数据库:mysql-5.5 数据库工具:emma

服务器:tomcat 服务器工具:Myeclipse 10(已配置好Struts2和Hibernate环境)

注意:

程序调试过程可能会产生乱码,只需保持所有工具编码方式相同即可。

二、项目文件配置

1、新建Web Project,命名为ROOT

2、配置/WebRoot/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ROOT</display-name> <filter>  <filter-name>struts2</filter-name>  <filter-class>     org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter   </filter-class> </filter> <filter-mapping>  <filter-name>struts2</filter-name>  <url-pattern>/*</url-pattern> </filter-mapping> <error-page>  <error-code>404</error-code>  <location>/error.jsp</location> </error-page> <error-page>  <error-code>500</error-code>  <location>/error.jsp</location> </error-page> <welcome-file-list>  <welcome-file>index.html</welcome-file>  <welcome-file>index.htm</welcome-file>  <welcome-file>index.jsp</welcome-file>  <welcome-file>default.html</welcome-file>  <welcome-file>default.htm</welcome-file>  <welcome-file>default.jsp</welcome-file> </welcome-file-list></web-app>

3 、 配置/src/struts.xml(struts配置文件),其他的action和interceptor被我删了,这点够用了。

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"><struts> <package name="default" namespace="/" extends="struts-default">  <!-- 登录 -->  <action name="login" class="com.action.Login" method="login"></action>  <!-- 登出 -->  <action name="logout" class="com.action.Logout" method="logout"></action>  <!-- 注册 -->   <action name="register" class="com.action.Register" method="register"></action>  <!-- 邮件发送 -->   <action name="sendmail" class="com.action.SendMail" method="sendmail"></action> </package></struts> 

4、配置/src/hibernate.cfg.xml(hibernate数据库配置文件),注意倒数第4行有个<mapping />是没有的需要自己创建,将在下一步配置

<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE hibernate-configuration PUBLIC   "-//Hibernate/Hibernate Configuration DTD 3.0//EN"   "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><!-- Generated by MyEclipse Hibernate Tools. --><hibernate-configuration> <session-factory>  <property name="myeclipse.connection.profile">Myeclipse Mysql</property>  <!--指明JDBC路径、指明数据库名称-->  <property name="connection.url">jdbc:mysql://localhost:3306/test</property>  <!--指明数据库账户和密码-->  <property name="connection.username">root</property>  <property name="connection.password">root</property>  <!--指明JDBC驱动-->  <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  <!--指明mysql方言-->  <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  <property name="hibernate.current_session_context_class">thread</property>  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>  <property name="show_sql">true</property>  <property name="format_sql">true</property>  <mapping resource="com/hibernate/bookchat.hbm.xml" /> </session-factory></hibernate-configuration>

5、/src下创建com.hibernate包,在该包下创建bookchat.hbm.xml(hibernate对象关系映射文件),并配置

注意<class name="com.hibernate.User" />中的这个User类是自定义的数据库对象类(pojo),将在下一步配置

<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <!--指明Bean类名,指明数据库表名--> <class name="com.hibernate.User" table="user">  <id column="id" type="int">   <generator class="native" />  </id>  <!--指明数据库字段名、字段类型-->  <property name="user_id" column="user_id" type="int" />  <property name="phone" column="phone" type="int" />  <property name="email" column="email" type="string" />  <property name="username" column="username" type="string" />  <property name="password" column="password" type="string" />  <property name="icon" column="icon" type="string" />  <property name="description" column="description" type="string" />  <property name="followThreadNum" column="followThreadNum" type="int" />  <property name="followPeopleNum" column="followPeopleNum" type="int" />  <property name="fansNum" column="fansNum" type="int" />  <property name="haveMsg" column="haveMsg" type="int" /> </class></hibernate-mapping>

6、/src下的com.hibernate包下创建User类

package com.hibernate;public class User { private int user_id; //对应数据库中user_id private int phone; //手机号 private String email; //邮件 private String username; //用户名 private String password; //密码 private String icon; //用户头像 private String description;  //自定义描述 private int followThreadNum; //关注书单数量 private int followPeopleNum; //关注的人数量 private int fansNum; //粉丝数量 private int haveMsg; //当前是否有新消息 public User() {  super(); }   //这个构造方法在注册时有用 public User(String email, String username, String password) {  // 用户内容:username,password,email  // 系统定义:user_id,icon,followThreadNum,followPeopleNum,fansNum,haveMsg  // 留空:phone,description,  this.user_id = 39212;  // this.phone = phone;  this.email = email;  this.username = username;  this.password = password;  this.icon = "images/icon.png";  // this.description = description;  this.followThreadNum = 0;  this.followPeopleNum = 0;  this.fansNum = 0;  this.haveMsg = 0; } public int getUser_id() {  return user_id; } public void setUser_id(int user_id) {  this.user_id = user_id; } public int getPhone() {  return phone; } public void setPhone(int phone) {  this.phone = phone; } public String getEmail() {  return email; } public void setEmail(String email) {  this.email = email; } public String getUsername() {  return username; } public void setUsername(String username) {  this.username = username; } public String getPassword() {  return password; } public void setPassword(String password) {  this.password = password; } public String getIcon() {  return icon; } public void setIcon(String icon) {  this.icon = icon; } public String getDescription() {  return description; } public void setDescription(String description) {  this.description = description; } public int getFollowThreadNum() {  return followThreadNum; } public void setFollowThreadNum(int followThreadNum) {  this.followThreadNum = followThreadNum; } public int getFollowPeopleNum() {  return followPeopleNum; } public void setFollowPeopleNum(int followPeopleNum) {  this.followPeopleNum = followPeopleNum; } public int getFansNum() {  return fansNum; } public void setFansNum(int fansNum) {  this.fansNum = fansNum; } public int getHaveMsg() {  return haveMsg; } public void setHaveMsg(int haveMsg) {  this.haveMsg = haveMsg; }}

7、/src下的com.db包下创建CreateTable类,之后Run as - Java Application,查看控制台是否输出了sql语句

package com.db;import org.hibernate.cfg.Configuration;import org.hibernate.tool.hbm2ddl.SchemaExport;public class CREATTABLEDONOT { public static void main(String[] args) {  // 默认读取hibernate.cfg.xml文件  Configuration cfg = new Configuration().configure();  SchemaExport export = new SchemaExport(cfg);  export.create(true, true); }}

三、检查数据库

1、打开数据库GUI工具,查看test数据库下是否有一个user表,若能打开user表说明之前配置成功。

2、编辑user表:设置字段默认值,可以向表中添加数据。

 

四、网页UI设计

1、我们在struts.xml文件配置中已经埋下伏笔:

<action name="login" class="com.action.Login" method="login"></action>
<action name="logout" class="com.action.Logout" method="logout"></action>
<action name="register" class="com.action.Register" method="register"></action>
<action name="sendmail" class="com.action.SendMail" method="sendmail"></action>

我们可以在网页中请求/login,/logout,/register来访问这三个Action处理类,当然这三个类具体的内容我们还没写,先放着。

2、现在开始思考网页设计需要什么东西...

<1> 首页提供登陆和注册链接

 

<2> 登陆弹出框和注册页面


<3> 登陆/注册成功,登陆和注册消失,显示用户名和退出登陆

 

<4> 我们想达到的效果:登陆/注册成功后显示用户名,登陆失败后动态提示错误详情!

五、JQuery+Ajax设计

1、 主要的JQuery和Ajax代码

(function(window, $) { var SOKK = {}; ys.common = SOKK; //邮箱验证 SOKK.sendmail = function(){  var email = $("#inputEmail").val().trim();  if(!checkEmail(email)){   return false;  }  //发送请求  $.get("/sendmail","email="+email,function(data){   data = JSON.parse(data);   tip(data.code);  }) } //注册 SOKK.signup = function(form){  var form = $(form);  //成功方可继续执行  if(!checkSignUp(form.find("input")))   return false;  //序列化表单,生成JSON对象  var JStr =form.serialize();  // var JStr = JSON.stringify(JForm);  tip(JStr);  $.post("/register",JStr,function(data){   data = JSON.parse(data);   if (data.code == 200) {    location.reload(); //如何跳转到首页?   } else {    tip(data.code);   }  }) }; // 登录 SOKK.login = function(form) {  var form = $(form);  var input = form.find("input");  var username=$.trim(input[0].value);  var password=$.trim(input[1].value);  if(checkLogin(username,password)){   return false;  }  var dataParam = {};  dataParam.username = username;  dataParam.password = password;  // 这里的dataParam是键值对,但服务器获取的时候是?username=xx&password=xx;  // 如果使用json传输那么就不能用这种方式而必须用$.ajax,而且json在服务器端还要再解析,  // 所以在发送请求时,不建议使用json。接受数据可以使用json  $.post("/login", dataParam, function(data) {   // json字符串->json对象   data = JSON.parse(data);   if (data.code == 200) {    location.reload();   } else {    tip(data.code);   }  }) }; //登出 SOKK.logout = function(){  $.get("/logout", function (data) {   //json字符串->json对象     data = JSON.parse(data);   if (data.code==200){    location.reload();   }  }) };})(window, $)

2、自定义工具代码

// 自定义提示function tip(info){ if(isNaN(info)){  toastr.info(info); }else{  var msg;  if(info<300){     switch(info){    case 100: msg="加入书架成功!"; break;    case 101: msg="关注本书成功!"; break;    case 102: msg="已移动到【正在看】!"; break;    case 103: msg="已移动到【准备看】!"; break;    case 104: msg="已移动到【已看完】!"; break;    case 105: msg="已移动到【回收站】!"; break;    case 110: msg="验证邮件已发送到你的邮箱!";break;    case 200: msg="请求成功!"; break;    case 202: msg="请求已接受,但尚未处理。"; break;    case 204: msg="请求成功,但无返回内容。"; break;    default : break;   }   toastr.success(msg);  }else if(info<1000){   switch(info){    case 301: msg="请求网页的位置发生改变!"; break;    case 400: msg="错误请求,请输入正确信息!"; break;    case 401: msg="非法请求,未授权进入此页面!"; break;    case 403: msg="拒绝请求!"; break;    case 404: msg="请求页面不存在!"; break;    case 408: msg="请求超时!"; break;    case 500: msg="服务器出错!"; break;    case 500: msg="服务不可用!"; break;    case 900: msg="用户名/密码错误,请重新输入"; break;    case 903: msg="服务器出错,请重试!"; break;    case 904: msg="服务器无返回信息!"; break;    case 905: msg="网络出错!"; break;    case 906: msg="注册失败,请重试!";break;    case 907: msg="邮箱验证码错误!";break;    case 908: msg="用户名已存在!";break;    case 909: msg="邮箱已被注册!";break;    case 910: msg="验证邮件发送失败!";break;    default : break;   }   toastr.error(msg);  }else{   toastr.info(info);  } }}//注册检查function checkSignUp(input){ var username = $.trim(input[0].value); var password1 = $.trim(input[1].value); var password2 = $.trim(input[2].value); var email = $.trim(input[3].value); var emailcode = $.trim(input[4].value); for (var i = 0; i < input.length; i++) {  if(input[i].value.length<=0){   tip("所有内容不得为空!");   return false;  } }; if(username.length<4){  tip("用户名不得少于4个字符!");  return false; } if(password1!==password2){  tip("两次输入的密码不同!");  return false; } if(password1.length<6){  tip("密码不得少于6个字符!");  return false; } return true;}function checkLogin(username,password){ if(!username){  tip("请输入用户名!");  return false; } if(!password){  tip("请输入密码!");  return false; }}function checkEmail(email){ var reg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/; if(email){  if(reg.test(email)){   return true;  }else{   tip("邮箱地址不符合规范!");   return false;  } }else{  tip("邮箱地址不得为空!");  return false; }}

3、toastr是一个前端非阻塞的提示插件,可以到 http://www.bootcdn.cn/toastr.js/ 下载使用

        

六、Action设计

1、Login.java

package com.action;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;import com.service.BaseService;import com.service.BaseServiceImpl;import com.util.OperateJSON;public class Login extends ActionSupport { private static final long serialVersionUID = 4679952956618457478L; private String username; private String password; public void login() {  HttpServletRequest request = ServletActionContext.getRequest();  BaseService hs = new BaseServiceImpl();  OperateJSON oj = new OperateJSON();  username = request.getParameter("username");  password = request.getParameter("password");  System.out.println("用户名:" + username + "--密码:" + password);  // 登陆返回用户id  Object obj = hs.login(username, password);  if (obj != null) {   System.out.println("用户名密码正确");   request.getSession().setAttribute("username", username);   request.getSession().setAttribute("userid", obj);   System.out.println("用户名" + username + "的Session设置完毕~");   System.out.println("用户id的Session设置完毕~");   oj.putCode(200);  } else {   System.out.println("用户名密码错误");   oj.putCode(900);  }  oj.send(); }}

2、Logout.java

package com.action;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;import com.util.OperateJSON;public class Logout extends ActionSupport { private static final long serialVersionUID = -6758897982192371466L; HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); OperateJSON oj = new OperateJSON(); public void logout() {  request.getSession().removeAttribute("username");  request.getSession().invalidate();  if (request.getSession().getAttribute("username") == null) {   oj.putCode(200);  } else {   oj.putCode(903);  }  oj.send(); }}

3、Register.java

package com.action;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts2.ServletActionContext;import com.hibernate.User;import com.opensymphony.xwork2.ActionSupport;import com.service.BaseService;import com.service.BaseServiceImpl;import com.util.OperateJSON;public class Register extends ActionSupport { private static final long serialVersionUID = -3356620731966076779L; HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); BaseService bs = new BaseServiceImpl(); OperateJSON oj = new OperateJSON(); SendMail sm = new SendMail(); public void register() {  String username = request.getParameter("username");  String password1 = request.getParameter("password1");  String password2 = request.getParameter("password2");  String password = (password1.equals(password2) ? password1 : null);  String email = request.getParameter("email");  String emailcode = request.getParameter("emailcode");  // 判断用户输入和生成的邮箱验证码是否相同  if (!(emailcode.equals(sm.getMailCode()))) {   oj.putCode(907);   oj.send();   return;  }  // 检测用户名/邮箱是否唯一  if (!bs.isUnique("User", "username", username)) {   oj.putCode(908);   oj.send();   return;  }  if (!bs.isUnique("User", "email", email)) {   oj.putCode(909);   oj.send();   return;  }  // 构建User对象  User user = new User(email, username, password);  // 建立对象关系映射  Boolean reged = bs.register(user);  if (reged) {   System.out.println("用户注册成功");   request.getSession().setAttribute("username", username);   oj.putCode(200);  } else {   System.out.println("注册失败");   oj.putCode(906);  }  oj.send(); }}

4、 SendMail.java  SMTP协议发送邮件的类,使用前需要导入mail的jar包,同时,还要设置开启发件人邮箱的smtp服务

package com.action;import java.util.Date;import java.util.Properties;import javax.mail.BodyPart;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Multipart;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;import com.util.OperateJSON;public class SendMail extends ActionSupport {  private static final long serialVersionUID = -4724909293302616101L;  private static String QQ = "392102018"; // qq  private static String HOST = "qq.com"; // SMTP服务器主机名  private static String PASS = "xxxxxxxx"; // SMTP服务器密码  private static String mailCode; // 邮件验证码  OperateJSON oj = new OperateJSON();  public void sendmail() { HttpServletRequest request = ServletActionContext.getRequest(); String email = request.getParameter("email"); System.out.println(email); String mailCode = SendMail.setMailCode(); try {   beginSend(email, mailCode);   oj.putCode(110); } catch (MessagingException e) {   oj.putCode(910); } finally {   oj.send(); }  }  public static String setMailCode() { mailCode = 100000 + (int) (Math.random() * 900000) + "BC"; System.out.println(mailCode); return mailCode;  }  public String getMailCode() { return SendMail.mailCode;  }  public void beginSend(String email, String mailCode)   throws MessagingException { String mailTo = email; // 收件方mail地址 String mailTitle = "欢迎您使用书聊网! 立即激活您的账户"; String mailContent = "<p>尊敬的用户:</p><p>你好!立即激活您的账户,和书聊网会员一起看书交流。要激活您的账户,只需复制下面的验证码到注册页面确认。 </p>"  + mailCode + "<p>版权所有© 1999 - 2015 BookChat。保留所有权利。</p>"; // 设置主要信息 Properties props = new Properties(); props.put("mail.smtp.host", "smtp." + HOST); props.put("mail.smtp.auth", "true"); Session session = Session.getInstance(props); session.setDebug(true); // 开启邮件对象 MimeMessage message = new MimeMessage(session); // 设置发件人/收件人/主题/发信时间 InternetAddress from = new InternetAddress(QQ + "@" + HOST); message.setFrom(from); InternetAddress to = new InternetAddress(mailTo); message.setRecipient(Message.RecipientType.TO, to); message.setSubject(mailTitle); message.setSentDate(new Date()); // 设置消息对象内容 BodyPart mdp = new MimeBodyPart();// 新建一个存放信件内容的BodyPart对象 mdp.setContent(mailContent, "text/html;charset=utf-8");// 给BodyPart对象设置内容和格式/编码方式 Multipart mm = new MimeMultipart();// 新建一个MimeMultipart对象用来存放BodyPart对象(事实上可以存放多个) mm.addBodyPart(mdp);// 将BodyPart加入到MimeMultipart对象中(可以加入多个BodyPart) message.setContent(mm);// 把mm作为消息对象的内容 message.saveChanges(); // 开启传输对象 Transport transport = session.getTransport("smtp"); transport.connect("smtp." + HOST, QQ, PASS); // 这里的115798090也要修改为您的QQ号码 transport.sendMessage(message, message.getAllRecipients()); transport.close();  }}

5、OpreateJSON

package com.util;import java.io.IOException;import java.io.PrintWriter;import org.apache.struts2.ServletActionContext;import net.sf.json.JSONObject;public class OperateJSON { JSONObject json; public OperateJSON() {  json = new JSONObject();  json.put("code", "");  json.put("msg", "");  json.put("data", ""); } public OperateJSON(String str) {  json = JSONObject.fromObject(str); } public void put(String key, Object value) {  json.remove(key);  json.put(key, value); } public void putCode(Object value) {  json.remove("code");  this.put("code", value); } public void putMsg(Object value) {  json.remove("msg");  this.put("msg", value); } public void remove(String key) {  json.remove(key); } public void send() {  System.out.println("----------返回的数据是:" + json);  try {   PrintWriter out = ServletActionContext.getResponse().getWriter();   out.print(json);   out.flush();  } catch (IOException e) {   e.printStackTrace();  } }}

七、Hibernate Dao设计

这块都是一些操作数据库的内容,大家都有自己的风格,仔细一点写就好了。代码太乱,我就不放出来吓人了-.-! 。

八、总结

开始想展示下结果的还是算了,也就那么回事。一个小例子,瑕疵难免,还望大神们指正。

写完了,心情好多了,招聘会去看看也好,找不找工作不重要,重要的是我走在正确的路上,只有依靠自己才是强者...


  • 上一条:
    理解jquery ajax中的datatype属性选项值
    下一条:
    ajax与传统web开发的异同点
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2017-09
    • 2018-01
    • 2018-07
    • 2018-08
    • 2018-09
    • 2018-12
    • 2019-01
    • 2019-02
    • 2019-03
    • 2019-04
    • 2019-05
    • 2019-06
    • 2019-07
    • 2019-08
    • 2019-09
    • 2019-10
    • 2019-11
    • 2019-12
    • 2020-01
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-12
    • 2024-02
    • 2024-04
    • 2024-05
    • 2024-06
    • 2025-02
    • 2025-07
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客