Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。
————————————————————————————————————-
为了演练我们前面学到的知识,因此我们做一个简单的及时通讯web项目,包括用户登录,用户在线列表,个人对个人聊天功能,设计界面如下(程序员出品必属渣品):

即时通讯界面
界面分为四部分:
1、登录框,无密码登录
2、在线用户列表,所有登录服务器的用户会显示在每个人的用户列表中
3、用户聊天记录,显示当前用户与另外一个用户的猎头记录,并在聊天过程中刷新聊天记录
4、用户聊天记录发送功能

这里使用了div控制界面的结构,整个界面作为一个div,占整个界面的90%,居中显示。整个界面又分为上下两部分,上面的部分高120px,下面的部分占全部空间。下部空间有分为左右两部分,分别为用户列表部分(35%),聊天窗口(65%)两部分。聊天窗口中分为聊天记录和聊天发送窗口两部分。我们在用户列表和聊天记录中添加了一些测试数据,我们在WEB-INFO/vm中添加master.vm,内容如下:

[code lang=”html”]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>
用户主页面
</title>
</head>
<body>

<div align="center">

<div style="width:90%">

<div style="height:120px">

<h1>
用户主界面
</h1>

<form action="#">
<input value="用户名" name="username" />
<input type="submit" value="提交" />
</form>

</div>

<div style="width:35%;height:400px; float:left;">

<h3>
用户列表
</h3>

<div id="userListDiv">

<table border="1">

<thead>

<tr>

<th width="30%">用户</th>

<th width="30%">最后登录时间</th>

<th width="20%">状态</th>

<th width="20%">操作</th>

</tr>

</thead>

<tbody>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

<tr>

<td >test1</td>

<td width="30%">2016-03-14 17:24:30</td>

<td width="20%">在线</td>

<td width="20%"><input type="button" value="聊天" /></td>

</tr>

</tbody>

</table>

<div id="userListPagination">

<div>
首页 上一页
<input value="1" style="width:20px;height:15px" url="/imlearntest/im/userList?1=1&limit=10" />
下一页 尾页
</div>

</div>

</div>

</div>

<div style="height:400px; width:1px; border-left:1px #000 solid;float:left;margin:5px;">
</div>

<div style="height:400px;float:left;width:55%;" id="chatDiv">

<h3>聊天窗口</h3>

<div id="chatRecordList">

<table border="1" width="100%">

<thead>

<tr>

<th>xxx的信息</th>

<th>你的信息</th>

</tr>

</thead>

<tbody id="chatLogTbody">

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

<tr>

<td colspan="2" align="left">hello</td>

</tr>

</tbody>

</table>

<div id="chatRecordPagination">

<div>
<a href="javascript:void(0);" url="/imlearntest${chatRecordPageModel.getFirstUrl()}">
首页
</a>
上一页
<input value="" style="width:20px;height:15px" url="/imlearntest${chatRecordPageModel.getBaseUrl()}" />
下一页
<a href="javascript:void(0);" url="/imlearntest${chatRecordPageModel.getLastUrl()}">
尾页
</a>
</div>

</div>

</div>

<div style="height:1px; width:100%; border-left:1px #fff solid;float:left;margin:5px;">
</div>

<div align="left">
<textarea rows="4" cols="60" id="messageTextarea">
</textarea>
<input type="button" value="发送" />
</div>

</div>

</div>

</div>

</body>
</html>
[/code]

 

虽然这里我一下子贴出了整个界面的html代码,但在真正的开发中是一点点调出来的。
创建MasterController类,用于显示主界面,映射路径为/master/index
具体类如下:

[code lang=”java”]
package com.sunhaojie.imlearntest.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("master")
public class MasterController {

@RequestMapping("index")
public String index(HttpServletRequest request, HttpServletResponse response) {
return "master";
}
}
[/code]

启动服务器,通过连接http://localhost:8080/imlearntest/master/index 就可以展示主界面了。

登录界面已经显示出来了,下面我们完成登录,在form中设置action路径

[code lang=”html”]

<form action="/imlearntest/user/login">
<input value="用户名" name="username" />
<input type="submit" value="提交" />
</form>

[/code]

定义用户模块控制层com.sunhaojie.imlearntest.controller.UserController,内容如下:

[code lang=”java”]
@Controller
@RequestMapping("user")
public class UserController {

@Autowired
private UserBo userBo;

@RequestMapping("login")
public void login(@ModelAttribute("username") String username, HttpServletRequest request,
HttpServletResponse response) throws IOException {
request.getSession().setAttribute("username", username);
userBo.login(username);
response.sendRedirect("/imlearntest/master/index");
}
}
[/code]

这里使用了response.sendRedirect路径跳转到“/imlearntest/master/index”

业务类com.sunhaojie.imlearntest.bo.UserBo登录时把com.sunhaojie.imlearntest.vo.UserStatusVo用户信息(用户名,状态和最近访问时间)写入静态属性userStatus 中,实现逻辑如下:

[code lang=”java”]
@Service
public class UserBo {
private static Map<String, UserStatusVo> userStatus = new Hashtable<String, UserStatusVo>();
public void login(String username) {
UserStatusVo userStatusVo = userStatus.get(username);
if (userStatusVo == null) {
userStatusVo = new UserStatusVo();
userStatus.put(username, userStatusVo);
}
userStatusVo.setUsername(username);
userStatusVo.setStatus(1);
userStatusVo.setLastHeartBeat(new Date());
}
}
public class UserStatusVo {
/**
* 用户名
*/
private String username;
/**
* 状态
*/
private int status;
/**
* 上一次心跳时间
*/
private Date lastHeartBeat;
}
[/code]

在界面端输入任意用户名,提交以后跳转的页面没有任何反应,因为我们没有对登录后的状态进行判断,修改模板中登录模块的代码如下:

[code lang=”html”]

<div style="height:120px">

<h1>
用户主界面
</h1>

#if($!{username})
<label>当前用户:$!{username}—-<font color="green" id="statusFont">状态:已登录</font></label>
<input type="hidden" value="$!{username}" id="usernameHiddenId"/>
#else

<form action="/imlearntest/user/login">
<input value="用户名" name="username" />
<input type="submit" value="提交" />
</form>

#end
</div>

[/code]

这里用到的是velocity的ifelse判断,在UserController中我们把用户的username写入了session,所以在velocity模板中$!{username}会有值存在,当登录后跳转到页面时,会展示username和绿色字体的”状态:已登录”。

小练习:在本地完成主界面和用户登录功能。