系统的源代码目录结构已经上传到SVN服务器
SVN地址:
https://svn.duapp.com/appid4x2erzscad
用户名/密码:
在群里
目前的界面设计暂时不用修改;界面布局后的HTML页面即为整个系统的基础界面;整理好第二期任务和文档,按照上次开会讨论的要求,各组单独打包发给团长(邮箱:[email protected]),2014/4/18前。
就目前各组情况,请分配大于等于1个人来负责前端界面优化。
1.把HTML布局全部换成JSP网页。
2.除了页面的静态资源且不会每次访问都会修改的内容,其余全部清空。
3.修改界面的静态图标(如果有,尽量没有图标,用浅一点的颜色块实现就好),设定背景透明,且没有立体效果。
4.对于界面的内容摆放位置更换,组内讨论修改即可;对于界面功能的删改必须和各个组交流。
1.对于至今HTML布局界面还只能在自己电脑的唯一浏览器可以完整显示的界面,全部重新布局,至少满足以下要求:
a.对于浏览器窗口的比例缩放,界面内容必须完整显示。
b.在不是太多内容显示的界面,或者是现在看完整个界面内容只需要稍微滑动一下滚动条的界面,一律去除滚动条,即一屏展示完所有内容(这个要求在布局时已经要求过,但是有的组在HTML布局的时候出现无底线的改动)。
c.界面上的一些多功能或者控件至今仍然使用一张静态图片糊弄的小组,请尽快修改(如,一个日历控件竟然是一个div贴个img)。
2.界面的适应性,除了在你们已有的IE系列和360浏览器外,还需要在Firefox和Chrome 上测试,不只是测试,还必须都满足要求。
3.各组的界面目前仍然无法面世,请多浏览优秀的网页和网页设计站点,然后修改页面的设计和体验效果,如果有技术上的问题,随时邮件或者电话联系团长。(注意:不要让技术的瓶颈限制了各组对界面的设计要求,只要不是太天马行空的体验效果且符合整体风格,技术上的问题请不用担心)
4.全部按照HTML5标准定义界面元素,在HTML5中标记过时且不再使用的标签或者控件就不许再使用(如,center、font标签)。
5.界面内容和元素使用jsp的标签从后台获取然后填充到界面。
不是前台界面优化的人就不需要了解后台实现问题,页面内容都是来自服务器后台整理产生,请时常和后台开发的人员讨论业务流程,防止产生不合理的体验方式。
整个系统的目录结构(仅页面目录):
Coursemap
|……
|--WebContent
| |……
| |--css
| |--js
|--img
|--WEB-INF
| |……
|--pages
|--index.jsp
以上是整个系统源代码目录结构,对于红色标记的部分是前台界面编码部分的目录。
Index.jsp是课程地图的站点首页,图中红色标记的是文件夹,具体用途可以根据名称得出。需要注意的是,禁止直接在文件夹根目录存放各组的数据文件,必须先建好小组文件夹。
现在前台界面优化的人儿们就只需要访问这些地方就好了,对于其它目录里的内容,可以查看,不能修改。
Ajax是实现网页与服务器异步交互的技术理念,此处说是理念,因为ajax只是一些技术的结合即可实现,没有新的语言或者开发方式,重点是javascript脚本。
以下是异步交互的实现方式图:
使用ajax的原因也是想要使用户体验不间断,但是不是强制使用一些ajax框架,因为这些实现都是javascript,只要实现用户在操作后等待结果的时候界面不是空白,且可以继续对其它业务进行处理或操作的体验方式即可。
1.组内讨论定义访问方式(POST/GET),对于特殊的资源需要不同的访问方式,如,特殊的servlet访问。
2. 组内讨论访问接口名称和数据返回类型,即,定义好访问名称,返回数据类型json、xml、字符串或者html都可以,根据需要组内讨论即可。但是能用json和字符串时就不要选择其它的数据类型了,以减少传输量。
3. 组间讨论公共的脚本框架,以便于浏览器不用加载重复的资源。
4.
JSP页面的初始内容不是在用户浏览器访问到页面之后获取,而是在用户访问某地址时,服务器把对应的资源全部写入到页面之后返回给用户(不要纠结为什么在用户在获取到页面之后还是在加载某些资源,在服务器端页面已经生成,只是在浏览器获取时不能快速一次性获取),所以,页面的初始内容不属于用户与服务器交互产生的数据,不需要脚本获取或者控制。但是在起初页面内容填充的时候需要JSP的标签,请配合前台页面优化的人一起完成。
Spring容器和struts2拦截器集成后台架构。
系统后台框架是spring和struts2集成,在“课程地图”系统目前使用到这两个框架,有些高端功能暂时没有使用到,在系统中,spring负责管理所有后台功能模块,struts2负责控制所有的外部请求和转发。
Coursemap
|……
|--src
| |--action层
| |--exception层
| |--domain层
| |--util包
| |--servlet包
| |--common包
| |--struts.xml
|
|--WebContent
| |……
| |
|--WEB-INF
| |……
| |--lib
|--spring.xml
|--web.xml
从源码目录结构说,在src中的所有后台服务源代码和struts配置文件。在WebContent/WEB-INF/下,lib是外部程序引用包存放的文件夹,spring.xml是spring配置文件,web.xml是网站的配置文件,用于给web服务器识别和加载使用。
对于web.xml配置文件,需要加载spring和struts2的驱动器,以及配置一些网站的基础设定。
Spring加载:
contextConfigLocation
/WEB-INF/spring.xml
org.springframework.web.context.ContextLoaderListener
Struts2加载:
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
struts2
/*
其余的基础配置
Session:
30
站点首页:
courseMap
index.html
index.htm
index.jsp
等等……
后台目前分为两大块,struts2控制模块和spring管理模块。其中spring管理的是系统的所有功能,分为三层,action功能定义、exception错误信息捕获和domain基础操作层。
配置案例:
UserAction来自spring配置文件中定义。
/WEB-INF/pages/test/test.jsp
/WEB-INF/pages/error.jsp
Struts2的强大功能在于自动接收外部请求参数。
例如:
当外部使用方法“gopain?ip=1.1.1.1”访问时,struts2拦截到请求,在配置中找到定义的“gopain”这个action节点,然后访问该节点定义好的class,并指定访问getUsers方法。
那么在UserAction类中,定义:
Peivate String ip;
Public String getIp(){return this.ip;}
Public void setIp(String ip){this.ip = ip;}
那么,在struts2把请求“gopain?ip=1.1.1.1”给UserAction类的时候,默认参数ip就接收并存储到成员ip中。
Struts2的控制设置全部在struts.xml文件中。
负责定义外部访问地址、内部调用方法以及页面转发。
在上面的那个配置案例中,
Action是指定外部访问地址;
Class是指定调用功能类;
Method是指明使用哪个方法;
对于一些简单且基础的访问跳转,如果无验证需要也可以不用添加class和method参数。因为struts2默认有一个缺省类来接收这种访问方式,默认的method是execute方法,且默认返回参数是“SUCCESS”。
对于action内部的节点result
Name属性是指定返回参数,所以此处也强调,method返回类型必须是String;
当result没有填写name值的时候,默认是表示name=“SUCCESS”。
Struts2根据返回参数来指定跳转页面。
此处还有页面的转发,在此配置案例中没有体现。
配置案例:
Spring有两种配置方式,一种是扫描注解,另一种就是使用配置文件。
由于配置文件的可读性更好,所以系统选择配置文件配置方式。
在spring管理的后台服务代码中,分为三层,action、exception和domain。
从以上的三个bean节点配置可以看出来,以上属于一个完整定义。
bean解释:
id是指明spring管理好后台所有的类之后对外暴露的调用名称;
class显然就是被重定义的类的全名;
scope默认是单模式,scope="prototype"指定后,会在每一次访问的时候创建一个实例;
内部的节点prototype是指定class内部成员引用的接口,需要在此指明其名称和该接口的实现类。
科普:
Action中接口成员的名称与其property中的name必须一致,且在action的类中定义的该接口的get和set方法。
对于特殊的某些功能要求也许不能使用struts2来处理,以免请求队列过长等候太久。此处就需要使用servlet来处理需要快速响应的请求。
至于如何让struts2和servlet共存且不相互影响的原理,在此就不说了,大家可以到我的一篇博客中查看:http://blog.csdn.net/gopain/article/details/16370987。
Servlet的配置方式也是不唯一,但是注解的方式确实不利于管理和查看,所以要求使用在web.xml文件中配置。
配置案例:
ImageServlet
com.coursemap.d.servlet.ImageServlet
ImageServlet
/imageServlet.servlet
其中,servlet节点是配置servlet的实现和调用类(servlet类),servlet-mapping节点是配置外部访问接口。
此处可以看到访问方式是/imageServlet.servlet,要求:
必须添加后缀名,且不能为do和action。
还有一些其它功能定义就是基础工具类,在util包里定义实现即可,如md5码转换、发送邮件等等。
/**
* 连接数据库
*@author gopain
*
*/
public class DBConnection {
privatestatic String user = "root";
privatestatic String passwd = "gopain";
privatestatic String database = "coursemap";
privatestatic String dbip = "localhost";
privatestatic String dbport = "3306";
privatestatic String dbdriver = "com.mysql.jdbc.Driver";
publicConnection getConnection() throws SQLException {
Stringurl = "jdbc:mysql://" + dbip + ":" + dbport + "/"+ database + "?useUnicode=true&characterEncoding=utf-8";
try{
Class.forName(dbdriver).newInstance();
}catch (Exception e) {
thrownew SQLException(e);
}
returnDriverManager.getConnection(url, user, passwd);
}
/**
* 关闭数据库资源
* @param connection 需要关闭的连接
* @param statement 预处理语句
* @param result 结果集
* @param position 自定义系统调用的位置,需要指明包名、类名以及方法名
*/
publicvoid close(Connection connection,PreparedStatement statement,ResultSetresult,String position){
try{
if(result!= null){
result.close();
result= null;
}
if(statement!= null){
statement.close();
statement= null;
}
if(connection!= null){
connection.close();
connection= null;
}
}catch(SQLExceptione){
e.printStackTrace();
System.out.println("Exceptionat: " + position);
}
}
}
1. 对于数据库连接资源,必须“节约”使用。在一次连接完成后必须关闭。
2. 每一个操作数据库的类继承以上的DBConnection即可。方便取得连接和关闭连接。
在此,我重要强调的是关闭数据库的时候的那个position参数,必须指定且说明详细,
如:
finally{
close(connection, statement, result, "package:com.coursemap.c.domain.impl\n"+
"class:UserDaoImpl \n method:getUsers() \nintent:获取用户列表");
}
还有,close方法是在finally中调用,大家应该懂。
3.每一次捕获错误都必须指明和注释。
如,
catch(Exception e) {
e.printStackTrace();
System.out.println("package:com.coursemap.c.domain.impl\n"+
"class:UserDaoImpl \n method:getUsers() \nintent:获取用户列表\n无法获取前10调用户的用户名和email");
}
以便于开发阶段调试和生产阶段的日志生成。