1.网站系统开发需要掌握的技术
一、界面和用户体验(Interface and User Experience)
1.1 知道如何在基本不影响用户使用的情况下升级网站。通常来说,你必须有版本控制系统(CVS、Subversion、Git等等)和数据备份机制(backup)。
1.2 除了浏览器,网站还有其他使用方式:手机、屏幕朗读器、搜索引擎等等。你应该知道在这些情况下,你的网站的运行状况。MobiForge提供了手机网站开发的一些相关知识。
二、安全性(Security)
2.1 不要明文(plain-text)储存用户的密码,要hash处理后再储存。
2.2 确认你的数据库连接信息的安全性。
三、性能(Performance)
3.1 只要有可能,就使用缓存(caching)。正确理解和使用HTTP caching与HTML5离线储存。
3.2 学习如何用gzip/deflate压缩内容(deflate方式更可取)。
3.3 浏览Yahoo的Exceptional Performance网站,里面有大量提升前端性能的优秀建议,还有他们的YSlow工具。Google的page speed则是另一个用来分析网页性能的工具。两者都要求安装Firebug。
3.4 如果你的网页用到大量的小体积图片(比如工具栏),就应该使用CSS Image Sprite,目的是减少http请求数。
3.5 大流量的网站应该考虑将网页对象分散在多个域名(split components across domains)。
3.6 静态内容(比如图片、CSS、JavaScript、以及其他cookie无关的网页内容)都应该放在一个不需要使用cookie的独立域名之上。因为域名之下如果有cookie,那么客户端向该域名发出的每次http请求,都会附上cookie内容。这里的一个好方法就是使用"内容分发网络"(Content Delivery Network,CDN)。
3.7 确保网站根目录下有favicon.ico文件,因为即使网页中根本不包括这个文件,浏览器也会自动发出对它的请求。所以如果这个文件不存在,就会产生大量的404错误,消耗光你的服务器的带宽。
四、搜索引擎优化(Search Engine Optimization,SEO)
4.1知道robots.txt的作用,以及搜索引擎蜘蛛的工作原理。
4.2使用Google的Webmaster Tools和Yahoo的Site Explorer
4.3知道存在着恶意或行为不正当的网络蜘蛛。
4.4如果你的网站有非文本的内容(比如视频、音频等等),你应该参考Google的sitemap扩展协议。
五、技术(Technology)
5.1 理解HTTP协议,以及诸如GET、POST、sessions、cookies之类的概念,包括"无状态"(stateless)是什么意思。
5.2 确保你的XHTML/HTML和CSS符合W3C标准,使得它们能够通过检验。这可以使你的网页避免触发浏览器的古怪行为(quirk),而且使它在"屏幕朗读器"和手机上也能正常工作。
5.3 理解浏览器如何处理JavaScript脚本。
5.4 理解网页上的JavaScript文件、样式表文件和其他资源是如何装载及运行的,考虑它们对页面性能有何影响。在某些情况下,可能应该将脚本文件放置在网页的尾部。
5.5 理解JavaScript沙箱(Javascript sandbox)的工作原理,尤其是如果你打算使用iframe。
5.6 知道JavaScript可能无法使用或被禁用,以及Ajax并不是一定会运行。记住,"不允许脚本运行"(NoScript)正在某些用户中变得流行,手机浏览器对脚本的支持千差万别,而Google索引网页时不运行大部分的脚本文件。
5.7 了解301重定向和302重定向之间的区别(这也是一个SEO相关问题)。
5.8 考虑使用样式表重置(Reset Style Sheet)。
5.9 考虑使用JavaScript框架(比如jQuery、MooTools、Prototype),它们可以使你不用考虑浏览器之间的差异。
六、解决bug
6.1 理解程序员20%的时间用于编码,80%的时间用于维护,根据这一点相应安排时间。
6.2 建立一个有效的错误报告机制。
6.3 建立某些途径或系统,让用户可以与你接触,向你提出建议和批评。
6.4 为将来的维护和客服人员撰写文档,解释清楚系统是怎么运行的。
6.5 经常备份!(并且确保这些备份是有效的。)除了备份机制,你还必须有一个恢复机制。
6.6 使用某种版本控制系统储存你的文件,比如Subversion或Git。
6.7 不要忘记做单元测试(Unit Testing),Selenium之类的框架会对你有用。
2.本次课堂测试的源程序代码
/*UserDaoImpl.java*/
1 package com.jaovo.msg.dao; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.util.ArrayList; 8 import java.util.List; 9 10 import com.jaovo.msg.Util.DBUtil; 11 import com.jaovo.msg.Util.UserException; 12 import com.jaovo.msg.model.User; 13 14 import sun.net.www.content.text.plain; 15 16 public class UserDaoImpl implements IUserDao{ 17 18 @Override 19 public void add(User user) { 20 //获得链接对象 21 Connection connection = DBUtil.getConnection(); 22 //准备sql语句 23 String sql="select count(*) from test_user where username = ?"; 24 //创建语句传输对象 25 PreparedStatement preparedStatement=null; 26 ResultSet resultSet=null; 27 try { 28 preparedStatement=connection.prepareStatement(sql); 29 preparedStatement.setString(1, user.getUsername()); 30 //接收结果集 31 resultSet=preparedStatement.executeQuery(); 32 //遍历结果集 33 while(resultSet.next()) 34 { 35 if(resultSet.getInt(1)>0)//>0说明数据库中已存在该用户 36 { 37 throw new UserException("用户已存在"); 38 } 39 } 40 sql="insert into test_user(username,password) value (?,?)"; 41 preparedStatement=connection.prepareStatement(sql); 42 preparedStatement.setString(1, user.getUsername()); 43 preparedStatement.setString(2, user.getPassword()); 44 preparedStatement.executeUpdate();//更改 45 } catch (SQLException e) { 46 // TODO Auto-generated catch block 47 e.printStackTrace(); 48 }finally { 49 DBUtil.close(resultSet); 50 DBUtil.close(preparedStatement); 51 DBUtil.close(connection); 52 } 53 54 } 55 56 @Override 57 public void delete(int id) { 58 Connection connection=DBUtil.getConnection(); 59 String sql="delete from test_user where id = ?"; 60 PreparedStatement preparedStatement=null; 61 try { 62 preparedStatement=connection.prepareStatement(sql); 63 preparedStatement.setInt(1,id); 64 preparedStatement.executeUpdate(); 65 } catch (SQLException e) { 66 // TODO Auto-generated catch block 67 e.printStackTrace(); 68 }finally { 69 DBUtil.close(preparedStatement); 70 DBUtil.close(connection); 71 } 72 73 } 74 75 @Override 76 public void update(User user) { 77 //获得链接对象 78 Connection connection = DBUtil.getConnection(); 79 //准备sql语句 80 String sql="update test_user set password = ? , where id = ?"; 81 //创建语句传输对象 82 PreparedStatement preparedStatement=null; 83 try { 84 preparedStatement=connection.prepareStatement(sql); 85 preparedStatement.setString(1,user.getPassword()); 86 preparedStatement.setInt(2, user.getId()); 87 preparedStatement.executeUpdate(); 88 } catch (SQLException e) { 89 // TODO Auto-generated catch block 90 e.printStackTrace(); 91 }finally { 92 DBUtil.close(preparedStatement); 93 DBUtil.close(connection); 94 } 95 } 96 97 @Override 98 public User load(int id) { 99 //获得链接对象 100 Connection connection = DBUtil.getConnection(); 101 //准备sql语句 102 String sql="select * from test_user where id = ?"; 103 //创建语句传输对象 104 PreparedStatement preparedStatement=null; 105 ResultSet resultSet=null; 106 User user=null; 107 try { 108 preparedStatement=connection.prepareStatement(sql); 109 preparedStatement.setInt(1,id); 110 resultSet=preparedStatement.executeQuery(); 111 while(resultSet.next()) { 112 user=new User(); 113 user.setId(id); 114 user.setUsername(resultSet.getString("username")); 115 user.setPassword(resultSet.getString("password")); 116 } 117 } catch (SQLException e) { 118 // TODO Auto-generated catch block 119 e.printStackTrace(); 120 }finally { 121 DBUtil.close(resultSet); 122 DBUtil.close(preparedStatement); 123 DBUtil.close(connection); 124 } 125 126 return user; 127 } 128 129 @Override 130 public User load(String username) { 131 //获得链接对象 132 Connection connection = DBUtil.getConnection(); 133 //准备sql语句 134 String sql="select * from test_user where username = ?"; 135 //创建语句传输对象 136 PreparedStatement preparedStatement=null; 137 ResultSet resultSet=null; 138 User user=null; 139 try { 140 preparedStatement=connection.prepareStatement(sql); 141 preparedStatement.setString(1,username); 142 resultSet=preparedStatement.executeQuery(); 143 while(resultSet.next()) { 144 user=new User(); 145 user.setId(resultSet.getInt("id")); 146 user.setUsername(username); 147 user.setPassword(resultSet.getString("password")); 148 } 149 } catch (SQLException e) { 150 // TODO Auto-generated catch block 151 e.printStackTrace(); 152 }finally { 153 DBUtil.close(resultSet); 154 DBUtil.close(preparedStatement); 155 DBUtil.close(connection); 156 } 157 158 return user; 159 } 160 161 @Override 162 public List<User> load() { 163 //获得链接对象 164 Connection connection = DBUtil.getConnection(); 165 //准备sql语句 166 String sql="select * from test_user"; 167 //创建语句传输对象 168 PreparedStatement preparedStatement=null; 169 ResultSet resultSet=null; 170 //集合中只能放入user对象 171 List<User>users=new ArrayList<User>(); 172 User user=null; 173 try { 174 preparedStatement=connection.prepareStatement(sql); 175 resultSet=preparedStatement.executeQuery(); 176 while(resultSet.next()) { 177 user=new User(); 178 user.setId(resultSet.getInt("id")); 179 user.setUsername(resultSet.getString("username")); 180 user.setPassword(resultSet.getString("password")); 181 users.add(user); 182 } 183 } catch (SQLException e) { 184 // TODO Auto-generated catch block 185 e.printStackTrace(); 186 }finally { 187 DBUtil.close(resultSet); 188 DBUtil.close(preparedStatement); 189 DBUtil.close(connection); 190 } 191 192 return users; 193 } 194 195 }
/*IUserDao.java*/
1 package com.jaovo.msg.dao; 2 import java.util.List; 3 import com.jaovo.msg.model.User; 4 5 public interface IUserDao { 6 public void add(User user); 7 public void delete(int id); 8 public void update(User user); 9 public User load(int id); 10 public User load(String username); 11 public List<User> load(); 12 13 }
/*User.java*/
1 package com.jaovo.msg.model; 2 3 public class User { 4 private int id; 5 private String username; 6 private String password; 7 public int getId() { 8 return id; 9 } 10 public void setId(int id) { 11 this.id = id; 12 } 13 public String getUsername() { 14 return username; 15 } 16 public void setUsername(String username) { 17 this.username = username; 18 } 19 public String getPassword() { 20 return password; 21 } 22 public void setPassword(String password) { 23 this.password = password; 24 } 25 }
/*UserException.java*/
1 package com.jaovo.msg.Util; 2 3 public class UserException extends RuntimeException{ 4 5 public UserException() { 6 super(); 7 // TODO Auto-generated constructor stub 8 } 9 10 public UserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 11 super(message, cause, enableSuppression, writableStackTrace); 12 // TODO Auto-generated constructor stub 13 } 14 15 public UserException(String message, Throwable cause) { 16 super(message, cause); 17 // TODO Auto-generated constructor stub 18 } 19 20 public UserException(String message) { 21 super(message); 22 // TODO Auto-generated constructor stub 23 } 24 25 public UserException(Throwable cause) { 26 super(cause); 27 // TODO Auto-generated constructor stub 28 } 29 }
/*DBUtil.java*/
1 package com.jaovo.msg.Util; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 9 public class DBUtil { 10 11 public static Connection getConnection() { 12 try { 13 //1 加载驱动 14 Class.forName("com.mysql.jdbc.Driver").newInstance(); 15 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 16 // TODO Auto-generated catch block 17 e.printStackTrace(); 18 } 19 String user = "root"; 20 String password = "root"; 21 String url = "jdbc:mysql://localhost:3306/test"; 22 Connection connection = null; 23 try { 24 //2 创建链接对象connection 25 connection = DriverManager.getConnection(url,user,password); 26 } catch (SQLException e) { 27 // TODO Auto-generated catch block 28 e.printStackTrace(); 29 } 30 return connection; 31 } 32 33 //关闭资源的方法 34 public static void close(Connection connection ) { 35 try { 36 if (connection != null) { 37 connection.close(); 38 } 39 40 } catch (SQLException e) { 41 // TODO Auto-generated catch block 42 e.printStackTrace(); 43 } 44 } 45 public static void close(PreparedStatement preparedStatement ) { 46 try { 47 if (preparedStatement != null) { 48 preparedStatement.close(); 49 } 50 51 } catch (SQLException e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 } 55 } 56 public static void close(ResultSet resultSet ) { 57 try { 58 if (resultSet != null) { 59 resultSet.close(); 60 } 61 62 } catch (SQLException e) { 63 // TODO Auto-generated catch block 64 e.printStackTrace(); 65 } 66 } 67 68 }
/*addInput.jsp*/
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <title>用户注册界面</title> 7 </head> 8 <body> 9 <%=request.getAttribute("error") %> 10 <form action="add.jsp" method="get"> 11 <h2 style="color:blue ; font-size:30px">用户注册</h2> 12 <table align="center" border="1" width="500"> 13 <tr> 14 <td>用户名称:</td> 15 <td> 16 <input type="text" name="username" /> 17 </td> 18 </tr> 19 <tr> 20 <td>用户密码:</td> 21 <td> 22 <input type="password" name="password"/> 23 </td> 24 </tr> 25 <tr align="center"> 26 <td colspan="2"> 27 <input type="submit" value="注册" /> 28 <input type="reset" name="重置" /> 29 </td> 30 </tr> 31 </table> 32 </form> 33 </body> 34 </html>
/*add.jsp*/
1 <%@page import="com.jaovo.msg.Util.UserException"%> 2 <%@page import="com.jaovo.msg.dao.UserDaoImpl" %> 3 <%@page import="com.jaovo.msg.model.User" %> 4 <%@ page language="java" contentType="text/html; charset=UTF-8" 5 pageEncoding="UTF-8"%> 6 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 7 <html> 8 <% 9 //接收客户端传递过来的参数 10 String username=request.getParameter("username"); 11 String password=request.getParameter("password"); 12 if(username==null || "".equals(username.trim())){ 13 request.setAttribute("error", "用户名不能为空");//设置error属性,属性值为“用户名不能为空” 14 %> 15 <jsp:forward page="addInput.jsp"></jsp:forward> 16 <% } 17 User user=new User(); 18 user.setUsername(username); 19 user.setPassword(password); 20 21 UserDaoImpl userDao=new UserDaoImpl(); 22 try{ 23 userDao.add(user); 24 %> 25 26 用户注册成功!<br> 27 <a href="http://www.baidu.com">百度</a> 28 <a href="addInput.jsp">继续添加</a><br> 29 <a href="list.jsp">用户列表</a> 30 <% 31 }catch(UserException e){ 32 %> 33 <h2 style="color:red ; font-size:50px">发生错误:<%=e.getMessage() %></h2> 34 <% 35 } 36 %> 37 </html>
/*list.jsp*/
1 <%@page import="com.jaovo.msg.model.User"%> 2 <%@page import="java.util.List"%> 3 <%@page import="com.jaovo.msg.dao.UserDaoImpl"%> 4 <%@ page language="java" contentType="text/html; charset=UTF-8" 5 pageEncoding="UTF-8"%> 6 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 7 <html> 8 <head> 9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 10 <title>用户展示界面</title> 11 </head> 12 <% 13 UserDaoImpl userDao=new UserDaoImpl(); 14 List<User> users=userDao.load(); 15 %> 16 <body> 17 <table align="center" border="1" width="500"> 18 <tr> 19 <td>用户编号</td> 20 <td>用户名称</td> 21 <td>用户密码</td> 22 </tr> 23 <% 24 for( User user : users){ 25 %> 26 <tr> 27 <td><%=user.getId() %></td> 28 <td><%=user.getUsername() %></td> 29 <td><%=user.getPassword() %></td> 30 <td><a href="delete.jsp ? id="<%=user.getId() %>" >删除</a></td> 31 32 </tr> 33 <% 34 } 35 %> 36 </table> 37 </body> 38 </html>
/*loginInput.jsp*/
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <title>用户登录</title> 7 </head> 8 <body> 9 <%=request.getAttribute("error") %> 10 <form action="login.jsp" method="get"> 11 <h2 style="color:blue ; font-size:30px">用户登录</h2> 12 13 <tr> 14 <td>用户名:</td> 15 <td> 16 <input type="text" name="username" /> 17 </td> 18 </tr><br> 19 <tr> 20 <td>密码:</td> 21 <td> 22 <input type="password" name="password"/> 23 </td> 24 </tr><br> 25 </tr> 26 <tr align="center"> 27 <td colspan="2"> 28 <input type="submit" value="登录" /> 29 <input type="reset" name="重置" /> 30 </td> 31 </tr> 32 </body> 33 </html>
/*login.jsp*/
1 <%@page import="com.jaovo.msg.Util.UserException"%> 2 <%@page import="com.jaovo.msg.dao.UserDaoImpl" %> 3 <%@page import="com.jaovo.msg.model.User" %> 4 <%@ page language="java" contentType="text/html; charset=UTF-8" 5 pageEncoding="UTF-8"%> 6 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 7 <html> 8 <% 9 //接收客户端传递过来的参数 10 UserDaoImpl userDao=new UserDaoImpl(); 11 User user=new User(); 12 String username=request.getParameter("username"); 13 String password=request.getParameter("password"); 14 user=userDao.load(username); 15 if(username==null || "".equals(username.trim())){ 16 request.setAttribute("error", "请输入用户名");//设置error属性,属性值为“请输入用户名” 17 %> 18 <jsp:forward page="loginInput.jsp"></jsp:forward> 19 <% 20 } 21 if(user==null||(user!=null&&!user.getPassword().contentEquals(password))) 22 { 23 request.setAttribute("error", "输入信息错误"); 24 %> 25 <jsp:forward page="loginInput.jsp"></jsp:forward> 26 <% 27 } 28 %> 29 用户登录成功!<br> 30 </html>
3.运行结果截图
4.列出你对这门课的希望和自己的目标,并具体列出你计划每周花多少时间在这门课上。
希望通过这门课的学习,真正和老师建立“教练与学员”的关系,自己要主动学习,多加练习,在动态网站这一领域打好基础,熟练掌握其一般要用到的语言,在实现功能的基础上更进一步,实现界面的美观,让用户使用便捷、舒适。
计划每周周一至周五抽出五小时左右,周末尽可能更多的时间来练习,以求掌握、领会更精湛的技术,提高编程能力。