网站的框架

网站的框架采用MV模式,即Model(模型)、View(视图)。框架将界面层和模型层进行分离,结构更清晰,更加方便管理代码。

其中上图框架中的修改和删除功能完成而添加查询模块没有编写

实现的系统页面样式如下:

             

      

下面贴出网站详细的代码:

1.Login.java

/**
*登录界面*/
package com.xidian;
import javax.servlet.http.*;
import java.io.*; public class Login extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
try{
//中文乱码
res.setContentType("text/html;charset=gbk");
PrintWriter pw=res.getWriter();
//返回登录界面
pw.println("<html>");
pw.println("<body bgcolor=#CDD4FF >");
pw.println("<center><img src=images/1.jpg width=120px height=150px><hr>"); //得到error信息
String info=req.getParameter("info");
if(info!=null){
pw.println("<h4>请正确登录!</h4>");
}
pw.println("<h3>登录界面<h3>");
pw.println("<form action=logincl method=post>");
pw.println("用户名:<input type=text name=username><br>");
pw.println("密码:<input type=password name=password><br>");
pw.println("<input type=checkbox name=keep value=2>保存Cookie<br>");
pw.println("<input type=submit name=login value=login><br>");
pw.println("</form>");
pw.println("</center><hr><img src=images/3.jpg width=120px height=150px>");
pw.println("<body>");
pw.println("<html>");
}
catch(Exception ex){
ex.printStackTrace();
}
}
public void doPost(HttpServletRequest req,HttpServletResponse res){
this.doGet(req,res);
}
}

2.LoginCl.java

 //处理界面
package com.xidian;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*; public class Logincl extends HttpServlet { //重写init函数,init只会在启动tomcat调用servlet时被执行
public void init(){ try {
//只会被调用一次
System.out.println ("init被调用"); //添加网页访问次数的功能
//创建一个FileReader
FileReader f=new FileReader("e://myDocument.txt");
BufferedReader br=new BufferedReader(f);
//读出一行数据
String numVal=br.readLine();
//一定要关闭文件流
br.close();
int times=Integer.parseInt(numVal);
//将times值放入到servletcontext
this.getServletContext().setAttribute("visitTimes",times+""); }
catch (Exception ex) {
}
} //重写destroy函数,destroy函数在tomcat关闭的时候被调用,要用shutdown.bat关,不能直接叉掉tomcat窗口
public void destroy(){
try {
System.out.println ("destroy被调用"); //再将新的次数写回去
FileWriter fw=new FileWriter("e://myDocument.txt");
BufferedWriter bw=new BufferedWriter(fw);
bw.write(this.getServletContext().getAttribute("visitTimes").toString());
bw.close();
}
catch (Exception ex) {
}
} public void doGet(HttpServletRequest req,HttpServletResponse res){
Connection ct=null;
PreparedStatement sm=null;
ResultSet rs=null;
try{
//接收用户名和密码
String u=req.getParameter("username");
String p=req.getParameter("password");
//调用UserBeanCl
UserBeanCl ubc=new UserBeanCl();
//使用UserBean方法
if(ubc.checkUser(u,p)){
//用户合法 //设置Cookie值
String keep=req.getParameter("keep");
if(keep!=null){
//将用户名和密码保存在客户端(cookie)
//创建Cookie
Cookie name=new Cookie ("myname",u);
Cookie pass=new Cookie("mypasswd",p);
//设置时间
name.setMaxAge(14*24*3600);
pass.setMaxAge(14*24*3600);
//回写到客户端
res.addCookie(name);
res.addCookie(pass);
} //设置Session值
HttpSession hs=req.getSession(true);
//1.修改session的存在时间
//hs.setMaxInactiveInterval(0);
//2.向session添加属性
hs.setAttribute("uname",u+""); //每登录一次在Session空间中添加计数器
String times=this.getServletContext().getAttribute("visitTimes").toString();
this.getServletContext().setAttribute("visitTimes",(Integer.parseInt(times)+1)+""); //跳转到Main页面
res.sendRedirect("Main"); } else{
//说明用户不存在
res.sendRedirect("login");//要到的servlet的那个url
}
}
catch(Exception ex){ ex.printStackTrace();
}finally{
try {
if(rs!=null){
rs.close();
}
if(sm!=null){
sm.close();
}
if(ct!=null){
ct.close();
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
} public void doPost(HttpServletRequest req,HttpServletResponse res){
this.doGet(req,res);
} }

3.Main.java

/**
*登录界面
* @version 1.00 2016/7/14
*/
package com.xidian;
import javax.servlet.http.*;
import java.io.*; public class Main extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
try{
//中文乱码处理
res.setContentType("text/html;charset=gbk");
PrintWriter pw=res.getWriter();
//返回登录界面
pw.println("<html>");
pw.println("<body bgcolor=#CDD4FF >");
pw.println("<center><img src=images/1.jpg width=120px height=150px><hr>");
pw.println("<h1>主界面</h1>");
pw.println("<a href=Welcome>管理用户</a><br>");
pw.println("<a href=???>添加用户</a><br>");
pw.println("<a href=???>查找用户</a><br>");
pw.println("<a href=???>安全退出</a><br>");
pw.println("</center><hr><img src=images/3.jpg width=120px height=150px>");
pw.println("<body>");
pw.println("<html>");
}
catch(Exception ex){
ex.printStackTrace();
}
} public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res);
} }

4.Welcome.java

//欢迎界面

package com.xidian;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
import java.util.*; public class Welcome extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
Connection ct=null;
PreparedStatement ps=null;
ResultSet rs=null; try {
//得到session
HttpSession hs=req.getSession(true);
String myName=(String)hs.getAttribute("uname");
String name="";
String passwd="";
//判断非法登录
if(myName==null){
//如果session中没有用户信息,再看看有没有cookie
// 从客户端得到所有cookie信息
Cookie [] allCookies=req.getCookies(); //如果allCookie不为空
if(allCookies!=null){
//从中取出cookie
for(int i=0;i<allCookies.length;i++){
//依次取出
Cookie temp=allCookies[i];
if(temp.getName().equals("myname")){
//得到cookie值
name=temp.getValue();
}else if(temp.getName().equals("mypasswd")){
passwd=temp.getValue();
}
}
if(!name.equals("")&&!passwd.equals("")){
//到logincl去验证
res.sendRedirect("logincl?username="+name+"&password="+passwd);
return;
}
} } //得到从logincl传递的用户名
String u=req.getParameter("uname");
//得到logincl传递的密码
String p=req.getParameter("upass");
//解决中文乱码问题
res.setCharacterEncoding("gbk"); PrintWriter pw=res.getWriter();
pw.println("<html>"); // pw.println("Welcome "+u+" upass="+p);
pw.println("<body bgcolor=#CDD4FF >");
pw.println("欢迎您:"+myName+"<img src=images/1.gif width=50px height=30px><center><img src=images/1.jpg width=120px height=150px><hr>");
pw.println("<h1>管理用户</h1>");
pw.println("<br><a href=login>返回重新登录</a>"); //===========分页的功能========================
int pageSize=5;//一页显示几条记录
int pageNow=1; //希望显示第几页 //动态接收pageNow
String sPageNow=req.getParameter("pageNow");
if(sPageNow!=null){
//用户不是第一次进入Welcome页面
pageNow=Integer.parseInt(sPageNow);
} //调用UserBeanCl
UserBeanCl ubc=new UserBeanCl();
ArrayList al=ubc.getResultByPage(pageNow,pageSize); pw.println("<table border=1>");
pw.println("<tr bgcolor=pink><th>id</th><th>name</th><th>passwd</th><th>email</th><th>grade</th><th>修改用户</th><th>删除用户</th></tr>");
//定义一个颜色数组
String [] mycol={"silver","pink"}; for(int i=0;i<al.size();i++){
UserBean ub=(UserBean)al.get(i);
pw.println("<tr bgcolor="+mycol[i%2]+">");
pw.println("<td>"+ub.getUserId()+"</td>");
pw.println("<td>"+ub.getUserName()+"</td>");
pw.println("<td>"+ub.getPasswd()+"</td>");
pw.println("<td>"+ub.getMail()+"</td>");
pw.println("<td>"+ub.getGrade()+"</td>");
pw.println("<td><a href=Update?uId="+ub.getUserId()+"&uName="+ub.getUserName()+"&uPasswd="+ub.getPasswd()+"&uEmail="+ub.getMail()+"&uGrade="+ub.getGrade()+">修改用户</td>");
pw.println("<td><a href=DelUserCl?userid="+ub.getUserId()+" onclick=\"return window.confirm('你确定要删除用户吗?')\">删除用户</td>");
pw.println("</tr>"); }
pw.println("</table>");
//显示上页
if(pageNow!=1)
pw.println("<a href=Welcome?pageNow="+(pageNow-1)+">"+"上一页"+"</a>");
//显示超链接
for(int i=pageNow;i<=pageNow+4;i++){
pw.println("<a href=Welcome?pageNow="+i+">"+i+"</a>");
}
//显示下页
int pageCount=ubc.getPageCount();
if(pageNow!=pageCount)
pw.println("<a href=Welcome?pageNow="+(pageNow+1)+">"+"下一页"+"</a>");
pw.println("该网页被访问了"+this.getServletContext().getAttribute("visitTimes").toString()+"次"+"<br>"); //指定跳转到某夜
//这里实际是一个表单
//你需要考虑的问题:输入的页数过大?,输入的不是数字?
pw.println("<form action=Welcome>");
pw.println("<input type=text name=pageNow> ");
pw.println("<input type=submit name=go> ");
pw.println("</form>"); pw.println("您的ip="+req.getRemoteAddr()+"<br>");
pw.println("您的机器名="+req.getRemoteHost()+"<br>"); pw.println("</center><hr><img src=images/3.jpg width=200px height=80px>");
pw.println("</html>"); } catch(Exception ex){
ex.printStackTrace();
} }
public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res);
} }

5.DelUserCl.java.

/**
处理删除某个用户
*/
package com.xidian;
import javax.servlet.http.*;
import java.io.*; public class DelUserCl extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
try{
//中文乱码
res.setContentType("text/html;charset=gbk");
//调用userBeanCl的删除用户的方法,完成删除
UserBeanCl ubc=new UserBeanCl();
//接收从Welcome.java中传递的id
String id=req.getParameter("userid");
if(ubc.delUser(id)){
//删除成功
res.sendRedirect("Ok");
}else{
//删除失败
res.sendRedirect("Err");
} }
catch(Exception ex){ ex.printStackTrace();
}
} public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res);
} }

6.Update.java

/**
* @(#)Login.java
*
*修改用户界面
* @author
* @version 1.00 2016/7/14
*/
package com.xidian;
import javax.servlet.http.*;
import java.io.*; public class Update extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
try{
//中文乱码
res.setContentType("text/html;charset=gbk");
PrintWriter pw=res.getWriter();
//返回登录界面
pw.println("<html>");
pw.println("<body bgcolor=#CDD4FF >");
pw.println("<center><img src=images/1.jpg width=120px height=150px><hr>");
pw.println("<h1>修改用户界面</h1>");
pw.println("<form action=UpdateCl>");
pw.println("<table border=1>");
pw.println("<tr><td>id</td><td><input readonly type=text name=uId value="+req.getParameter("uId")+"></td></tr>");
pw.println("<tr><td>name</td><td><input readonly type=text value="+req.getParameter("uName")+"></td></tr>");
pw.println("<tr><td>passwd</td><td><input type=text name=newPasswd value="+req.getParameter("uPasswd")+"></td></tr>");
pw.println("<tr><td>email</td><td><input type=text name=newEmail value="+req.getParameter("uEmail")+"></td></tr>");
pw.println("<tr><td>grade</td><td><input type=text name=newGrade value="+req.getParameter("uGrade")+"></td></tr>");
pw.println("<tr><td colspan=2><input type=submit value=修改用户></td></tr>");
pw.println("</table></form>");
pw.println("</center><hr><img src=images/3.jpg width=120px height=150px>");
pw.println("<body>");
pw.println("<html>");
}
catch(Exception ex){ ex.printStackTrace();
}
} public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res);
} }

7.UpdateCl.java

/**
处理修改某个用户
*/
package com.xidian;
import javax.servlet.http.*;
import java.io.*; public class UpdateCl extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
try{
//中文乱码
res.setContentType("text/html;charset=gbk");
UserBeanCl ubc=new UserBeanCl();
if(ubc.updateUser(req.getParameter("uId"),req.getParameter("newEmail"),req.getParameter("newPasswd"),req.getParameter("newGrade"))){
//删除成功
res.sendRedirect("Ok");
}else{
//删除失败
res.sendRedirect("Err");
} }
catch(Exception ex){ ex.printStackTrace();
}
} public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res);
} }

8. Ok.java

/**
操作成功界面
*/
package com.xidian;
import javax.servlet.http.*;
import java.io.*; public class Ok extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
try{
//中文乱码
res.setContentType("text/html;charset=gbk");
PrintWriter pw=res.getWriter();
//返回登录界面
pw.println("<html>");
pw.println("<body bgcolor=#CDD4FF >");
pw.println("<center><img src=images/1.jpg width=120px height=150px><hr>"); pw.println("<h1>恭喜你,操作成功!</h1>");
pw.println("<a href=Main>返回主界面</a>&nbsp;&nbsp;&nbsp;<a href=Welcome>返回管理用户</a>");
pw.println("</center><hr><img src=images/3.jpg width=120px height=150px>");
pw.println("<body>");
pw.println("<html>");
}
catch(Exception ex){ ex.printStackTrace();
}
} public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res);
} }

9.Err.java

/**
操作失败界面
*/
package com.xidian;
import javax.servlet.http.*;
import java.io.*; public class Err extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){
try{
//中文乱码
res.setContentType("text/html;charset=gbk");
PrintWriter pw=res.getWriter();
//返回登录界面
pw.println("<html>");
pw.println("<body bgcolor=#CDD4FF >");
pw.println("<center><img src=images/1.jpg width=120px height=150px><hr>"); pw.println("<h1>很遗憾,操作失败!</h1>");
pw.println("</center><hr><img src=images/3.jpg width=120px height=150px>");
pw.println("<body>");
pw.println("<html>");
}
catch(Exception ex){ ex.printStackTrace();
}
} public void doPost(HttpServletRequest req,HttpServletResponse res){ this.doGet(req,res);
} }

10.ConnDB.java

//从数据库中得到连接
package com.xidian;
import java.sql.*; import javax.sql.*;
import javax.naming.*; public class ConnDB{ private Connection ct=null;
public Connection getConn(){
/*try {
//连接数据库
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
//得到连接
ct=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test","sa","dba");
}
catch (Exception ex) {
ex.printStackTrace();
}
*/ try { //创建一个上下文环境
Context ctt=new javax.naming.InitialContext();
//通过con得到数据源
DataSource ds=(DataSource)ctt.lookup("java:comp/env/mydb");
ct=ds.getConnection();
System.out.println("使用连接池的方式"); }
catch (Exception ex) {
ex.printStackTrace();
}
return ct;
} }

11.UserBean.java

//这是一个UserBean<----->users表映射
//它的一个对象<----->users表的一条记录对应
//数据 package com.xidian; public class UserBean{ private int userId;
private String userName;
private String passwd;
private String email;
private int grade; public void setUserId(int userId){
this.userId=userId;
}
public int getUserId(){
return this.userId;
} public void setUserName(String userName){
this.userName=userName;
}
public String getUserName(){
return this.userName;
} public void setPasswd(String passwd){
this.passwd=passwd;
}
public String getPasswd(){
return this.passwd;
} public void setMail(String email){
this.email=email;
}
public String getMail(){
return this.email;
} public void setGrade(int grade){
this.grade=grade;
}
public int getGrade(){
return this.grade;
} }

12.UserBeanCl.java

 //这是一个处理类(处理users表)操作UserBean
//业务逻辑 package com.xidian;
import java.sql.*;
import java.util.*; public class UserBeanCl { private Connection ct=null;
private PreparedStatement ps=null;
private ResultSet rs=null;
private int pageCount=0; //共有几页(计算) //修改用户
public boolean updateUser(String id,String email,String passwd,String grade){
boolean b=false;
try{
ConnDB cd=new ConnDB();
ct=cd.getConn();
String sql="update users set passwd='"+passwd+"',email='"+email+"',grade='"+grade+"' where userId='"+id+"'";
ps=ct.prepareStatement(sql);
int num=ps.executeUpdate();
if(num==1){
//修改成功!
b=true;
}else{
//修改失败! }
}
catch(Exception ex){
ex.printStackTrace();
}finally{
this.close(); }
return b;
} //删除用户
public boolean delUser(String id){
boolean b=false;
try{
ConnDB cd=new ConnDB();
ct=cd.getConn();
String sql="delete from users where userId='"+id+"'";
ps=ct.prepareStatement(sql);
int num=ps.executeUpdate();
if(num==1){
//删除成功!
b=true;
}else{
//删除失败! }
}
catch(Exception ex){
ex.printStackTrace();
}finally{
this.close(); }
return b;
} //返回pageCount
public int getPageCount(){
return this.pageCount;
} //分页显示
public ArrayList getResultByPage(int pageNow,int pageSize){
ArrayList al=new ArrayList(); try{
int rowCount=0; //共有几条记录(查表) //得到rowCount
ConnDB cd=new ConnDB();
ct=cd.getConn();
ps=ct.prepareStatement("select count(*) from users");
rs=ps.executeQuery();
if(rs.next()){
rowCount=rs.getInt(1);
}
//计算pageCount
if(rowCount%pageSize==0){
pageCount=rowCount/pageSize;
}else{
pageCount=rowCount/pageSize+1;
}
ps=ct.prepareStatement("select top "+pageSize+" * from users where userId not in (select top "+pageSize*(pageNow-1)+" userId from users)");
//给?号赋值
// ps.setInt(1,pageSize);
// ps.setInt(2,pageSize*(pageNow-1)); rs=ps.executeQuery();
while(rs.next()){
//将rs中的每条记录封装到UserBean ub
UserBean ub=new UserBean();
ub.setUserId(rs.getInt(1));
ub.setUserName(rs.getString(2));
ub.setPasswd(rs.getString(3));
ub.setMail(rs.getString(4));
ub.setGrade(rs.getInt(5));
//将ub放入到集合ArrayList中
al.add(ub); } }
catch(Exception ex){
ex.printStackTrace();
}finally{
this.close();
} return al; } //验证用户 public boolean checkUser(String u,String p){ boolean b=false;
try{
ConnDB cd=new ConnDB();
ct=cd.getConn();
ps=ct.prepareStatement("select top 1 passwd from users where username= '"+u+"'and passwd='"+p+"'");
rs=ps.executeQuery();
if(rs.next()){
String dbPasswd=rs.getString(1);
if(dbPasswd.equals(p)){
b=true;
}
}
}
catch(Exception ex){
ex.printStackTrace();
}finally{
this.close();
} return b;
} //关闭资源
public void close(){ try {
if(rs!=null){
rs.close();
}
if(ps!=null){
ps.close();
}
if(ct!=null){
ct.close();
} }
catch (Exception ex) {
ex.printStackTrace();
}
} }

Servlet—简单的管理系统的更多相关文章

  1. SpringBoot + Layui + JustAuth +Mybatis-plus实现可第三方登录的简单后台管理系统

    1. 简介   在之前博客:SpringBoot基于JustAuth实现第三方授权登录 和 SpringBoot + Layui +Mybatis-plus实现简单后台管理系统(内置安全过滤器)上改造 ...

  2. 使用jsp/servlet简单实现文件上传与下载

    使用JSP/Servlet简单实现文件上传与下载    通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...

  3. IDEA新建javaWeb以及Servlet简单实现

    刚开始用IDEA开发,还不太熟悉,因此写一个教程,加深印象 1.新建一个Web项目 两种方法:java 和 Java Enterprise(推荐) 第一种)通过Java工程创建,这个方法需要手动导入T ...

  4. Intellij IDEA创建javaWeb以及Servlet简单实现

    1.创建web工程 File --> New --> Project...

  5. Servlet简单总结(一)

    一.Servlet简单总结 1.1. 什么是Servlet Servlet是JavaEE三大组建之一,是使用Java语言编写服务器端的程序,主要用来处理Web应用程序中的请求-响应.Servlet并没 ...

  6. Intellijidea建javaWeb以及Servlet简单实现

    一.创建并设置javaweb工程1.创建javaweb工程File --> New --> Project... 点击Project后出现如下界面,选择Java Enterprise,选中 ...

  7. JavaWeb基础之Servlet简单实现用户登陆

    学习javaweb遇到了一些坑,一些问题总结下来,记个笔记. 学习servlet遇到的一些坑: servlet实现用户登陆遇到的坑解决办法: https://www.cnblogs.com/swxj/ ...

  8. web实践小项目<一>:简单日程管理系统(涉及html/css,javascript,python,sql,日期处理)

    暑假自学了些html/css,javascript和python,苦于学完无处练手几乎过目即忘...最后在同学的建议下做了个简单日程管理系统.借第一版完成之际,希望能将实践期间犯过的错误和获得的新知进 ...

  9. [转]Intellij idea创建javaWeb以及Servlet简单实现

    准备:1. 安装jdk1.72. 安装tomcat1.8 一.创建并设置javaweb工程 1.创建javaweb工程File --> New --> Project... 设置工程名字: ...

随机推荐

  1. Jasmine入门(结合示例讲解)

    参考: http://www.cnblogs.com/wushangjue/p/4541209.html http://keenwon.com/1191.html http://jasmine.git ...

  2. KnockoutJS 3.X API 第四章 表单绑定(11) options绑定

    目的 options绑定主要用于下拉列表中(即<select>元素)或多选列表(例如,<select size='6'>).此绑定不能与除<select>元素之外的 ...

  3. 手把手教你实现一个完整的 Promise

    用过 Promise,但是总是有点似懂非懂的感觉,也看过很多文章,还是搞不懂 Promise的 实现原理,后面自己边看文章,边调试代码,终于慢慢的有感觉了,下面就按自己的理解来实现一个 Promise ...

  4. 在SSIS中的不同组件间使用局部临时表

    Connetion的属性RetainSameConnection是个boolean值,指定是否保持相同的链接,默认值是false,表示每个component都会单独的使用connection,在com ...

  5. 手动为php安装memcached扩展模块

    最近公司需要新部署几台服务器,主要就是lnmp平台,这几台服务器需要部署公司的系统,由于本屌刚入职时间不长,加上又是新手,所以对公司的架构一头雾水,前前后后折腾了一个月时间,终于磕磕绊绊的将系统服务器 ...

  6. WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要有三种实现方式 ...

  7. java基础复习 - 自动装箱

    Integer a = 127; // 将整形127装箱对象 Integer b = 127; // 同上 System.out.print( a==b ); // true System.out.p ...

  8. java中得到classpath和当前类的绝对路径的一些方法(路径中的%20"进行替换空格)

    原网址:http://blog.csdn.net/shendl/article/details/1427475 (注意:利用下面方式得到路径,如果路径中有空格字符, 那么会有"%20&quo ...

  9. Testing - 测试基础 - 模型

    珠玉在前,不再赘言. 软件测试模型 软件测试模型汇总

  10. js每天进步一点点3

    JS之样式的改变