The previous section http://blog.csdn.net/shymi1991/article/details/51985371
This chapter implements functions such as user registration, login, posting on Weibo, and commenting on Weibo.
1. Configuration file
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 使Spring支持自动检测组件,如注解的Controller -->
<mvc:annotation-driven/>
<context:component-scan base-package="com.weibo.dashboard.controller" />
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>apolication/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->
</list>
</property>
</bean>
</beans>
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>web app</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 初始化参数,加载spring容器配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring-mybatis.xml</param-value>
</context-param>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring监听器,服务器一启动就加载spring的配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 防止Spring内存溢出监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- springmvc的前端控制器 -->
<servlet>
<servlet-name>dispatch</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatch</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 对静态资的请求交由默认的servlet进行处理 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.eot</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.svg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.ttf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.woff</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.txt</url-pattern>
</servlet-mapping>
</web-app>
2. spring mvc controller
Encapsulate response data
package com.weibo.util;
public class ResponseData {
public Object data;
public ResponseData(Object data){
this.data = data;
}
}
UserControler.java
package com.weibo.dashboard.controller;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.weibo.dashboard.entity.User;
import com.weibo.dashboard.service.UserService;
import com.weibo.util.ResponseData;
@RestController
@RequestMapping(value="/user")
public class UserController {
@Resource
UserService userService;
@ResponseBody
@RequestMapping(value="/{name}",method=RequestMethod.GET)
public ResponseData findUser(@PathVariable("name")String name){
User user = userService.select(name);
return new ResponseData(user);
}
@ResponseBody
@RequestMapping(value="/login",method=RequestMethod.POST)
public ResponseData accountValid(@RequestBody User user){
boolean res = userService.accountValid(user);
return new ResponseData(res);
}
@ResponseBody
@RequestMapping(value="/new",method=RequestMethod.POST)
public ResponseData insert(@RequestBody User user){
userService.insert(user);
return new ResponseData(user);
}
}
PostController.java
package com.weibo.dashboard.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.weibo.dashboard.entity.Post;
import com.weibo.dashboard.service.PostService;
import com.weibo.util.ResponseData;
@RestController
@RequestMapping(value="/post")
public class PostController {
@Resource
PostService postService;
@ResponseBody
@RequestMapping(value="/show",method=RequestMethod.GET)
public ResponseData findList(){
List<Post> list = postService.findList();
return new ResponseData(list);
}
@ResponseBody
@RequestMapping(value="/show/{userName}",method=RequestMethod.GET)
public ResponseData findList(@PathVariable("userName") String userName){
List<Post> list = postService.postByUser(userName);
return new ResponseData(list);
}
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
public int delete(@PathVariable("id") int id){
int res = postService.delete(id);
return res;
}
@ResponseBody
@RequestMapping(value="/new",method=RequestMethod.POST)
public ResponseData add(@RequestBody Post post){
postService.insert(post);
return new ResponseData(post);
}
@RequestMapping(value="/likes/{id}/{flag}",method=RequestMethod.GET)
public void likeOrDislike(@PathVariable("id") int id,@PathVariable("flag") boolean flag){
if(flag){
postService.like(id);
}else{
postService.dislike(id);
}
}
}
CommentController.java
package com.weibo.dashboard.controller;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.weibo.dashboard.entity.Comment;
import com.weibo.dashboard.service.CommentService;
import com.weibo.util.ResponseData;
@RestController
@RequestMapping(value="/comment")
public class CommentController {
@Resource
CommentService commentService;
@RequestMapping(value="/new",method=RequestMethod.POST)
public ResponseData add(@RequestBody Comment comment){
commentService.insert(comment);
return new ResponseData(comment);
}
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
public void delete(@PathVariable("id") int id){
commentService.delete(id);
}
}
3. Front-end framework
The front end of the project references the angularJS library, bootstrap library and jquery library (because bootstrap depends on jquery). We focus on the js files under the js folder that are directly related to the logic of this project.
index.html
<!DOCTYPE html>
<html lang="en" data-ng-app="app">
<head>
<meta charset="utf-8" />
<title>Web Project</title>
<link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.css"
type="text/css" />
<link rel="stylesheet" href="css/font-awesome.min.css"
type="text/css" />
<link rel="stylesheet" href="css/app.css" type="text/css" />
<link rel="stylesheet" href="css/font.css" type="text/css" />
</head>
<body ng-app="app">
<div ng-view></div>
<div ng-include="commonviews/page_footer.html"></div>
<!--Angular -->
<script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular/angular-resource.min.js"></script>
<script src="vendor/angular/angular-route.min.js"></script>
<script src="vendor/angular/angular-cookies.min.js"></script>
<!-- jquery -->
<script src="vendor/jquery/jquery-1.11.1.js"></script>
<!-- bootstrap -->
<script src="vendor/bootstrap/js/bootstrap.js"></script>
<!-- App -->
<script src="js/app/app.js"></script>
<script src="js/app/common.js"></script>
<script src="js/controllers/homeController.js"></script>
<script src="js/controllers/signinController.js"></script>
<script src="js/controllers/signupController.js"></script>
<script>
</script>
</body>
</html>
app.js dependency injection, configuration routing
'use strict';
var app = angular.module('app', [
'ngRoute',
'ngResource',
]);
app.config(['$routeProvider',function ($routeProvider) {
$routeProvider.when('/signin',{
templateUrl:'commonviews/signin.html',
controller:'signinCtrl'
})
.when('/signup',{
templateUrl:'commonviews/signup.html',
controller:'signupCtrl'
})
.when('/home',{
templateUrl:'dashboard/home.html',
controller:'homeCtrl'
})
.otherwise({redirectTo:'/signin'
});
}]);
app.run(['$rootScope','$resource',function($rootScope,$resource){
$rootScope.user={};
}]);
common.js sets and reads cookies
function setCookie(c_name, value, expiredays) {
var exdate = new Date()
exdate.setDate(exdate.getDate() + expiredays)
document.cookie = c_name + "=" + escape(value)
+ ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString())
}
function getCookie(c_name) {
if (document.cookie.length > 0) {
c_start = document.cookie.indexOf(c_name + "=")
if (c_start != -1) {
c_start = c_start + c_name.length + 1
c_end = document.cookie.indexOf(";", c_start)
if (c_end == -1)
c_end = document.cookie.length
return unescape(document.cookie.substring(c_start, c_end))
}
}
return ""
}
3.1 User registration
signupController.js
app.controller('signupCtrl',function ($rootScope,$scope,$resource,$location) {
$scope.user={};
$scope.validUsername=true;
$scope.signup = function () {
var userResource = $resource('user/new', {}, {add:{method:'POST',responseType:"application/json;charset=UTF-8"}});
userResource.save({},$scope.user, function (res) {
alert("signup success");
var user = res.data;
$rootScope.user.name=$scope.user.name;
$location.path("/signin");
}, function (data) {
alert("signup faliure");
});
};
$scope.validateName = function(){
var userResource = $resource('user/:name',{name:$scope.user.name},{query:{method:'GET',isArray:false}});
if($scope.user.name!=undefined){
userResource.query({name:$scope.user.name},function(res){
if(res.data!=null){
$scope.validUsername=false;
}else{
$scope.validUsername=true;
}
});
}
else{
$scope.validUsername=true;
}
};
});
signup.html
<div class="container w-xxl w-auto-xs">
<a href class="navbar-brand block m-t">Weibo</a>
<div class="m-b-lg">
<div class="wrapper text-center">
<strong>Signup</strong>
</div>
<form name="form" class="form-validation">
<div class="text-danger wrapper text-center" ng-show="authError">
{
{authError}}</div>
<div class="list-group list-group-sm">
<div class="list-group-item">
<input id="username" placeholder="nick name"
class="form-control no-border" ng-model="user.name"
ng-blur="validateName()" required>
<div class="tip" style="top: 13px; left: 332px;"
ng-show="!validUsername">Username exits!</div>
</div>
<div class="list-group-item">
<input type="password" placeholder="Password"
class="form-control no-border" ng-model="user.password" required>
</div>
</div>
<div class="checkbox m-b-md m-t-none">
<label class="i-checks"> <input type="checkbox"
ng-model="agree" required><i></i> Agree the <a href>terms
and policy</a>
</label>
</div>
<button type="submit" class="btn btn-lg btn-primary btn-block"
ng-click="signup()" ng-disabled='form.$invalid||!validUsername'>Sign
up</button>
<div class="line line-dashed"></div>
<p class="text-center">
<small>Already have an account?</small>
</p>
<a href="#signin" class="btn btn-lg btn-default btn-block">Sign
in</a>
</form>
</div>
</div>
3.2 User login
signinController.js
app.controller('signinCtrl', ['$rootScope', '$scope', '$resource','$location', function($rootScope, $scope, $resource, $location) {
$scope.user = $rootScope.user;
$scope.authError = null;
$scope.login = function() {
var userResource = $resource('user/login', {}, {login:{method:'POST'}});
userResource.login({},$scope.user, function (res) {
if(res.data==true){
setCookie("username", $scope.user.name,1);
$location.path("/home");
}else{
$scope.authError = "Authentication faliure";
}
}, function (res) {
$scope.authError = "Server error";
});
};
}]);
signin.html
<div class="container w-xxl w-auto-xs">
<a href class="navbar-brand block m-t">Weibo</a>
<div class="m-b-lg">
<div class="wrapper text-center">
<strong>Sign in</strong>
</div>
<form name="form" class="form-validation">
<div class="text-danger wrapper text-center" ng-show="authError">
{
{authError}}</div>
<div class="list-group list-group-sm">
<div class="list-group-item">
<input type="text" placeholder="nick name"
class="form-control no-border" ng-model="user.name">
</div>
<div class="list-group-item">
<input type="password" placeholder="Password"
class="form-control no-border" ng-model="user.password">
</div>
</div>
<button type="submit" class="btn btn-lg btn-primary btn-block"
ng-click="login()" ng-disabled='form.$invalid'>Log in</button>
<div class="text-center m-t m-b">
<a href="#forgotpwd">Forgot password?</a>
</div>
<div class="line line-dashed"></div>
<p class="text-center">
<small>Do not have an account?</small>
</p>
<a href="#signup" class="btn btn-lg btn-default btn-block">Create
an account</a>
</form>
</div>
</div>
3.3 Main interface
homeController.js
app.controller('homeCtrl',['$scope','$resource','$location',function($scope,$resource,$location){
var username = getCookie("username");
console.log("cookies...",username);
if(username=='undefined'){
$location.path("/signin");
}
$scope.showPosts = function() {
var postResource = $resource('post/show', {}, {query:{method:'GET',isArray:false}});
postResource.query({},function(res){
$scope.postList = res.data;
}, function (res) {
console.log("error");
});
};
$scope.addPost = function() {
var postResource = $resource('post/new', {}, {save:{method:'POST'}});
$scope.post.authorName = username;
postResource.save({},$scope.post,function (res) {
$scope.showPosts();
}, function (res) {
console.log("error");
});
};
$scope.setReplyPostId = function(id){
$scope.replyPostId = id;
}
$scope.addComment = function() {
$scope.comment.cAuthorName = username;
$scope.comment.postId=$scope.replyPostId;
var commentResource = $resource('comment/new', {}, {save:{method:'POST'}});
commentResource.save({},$scope.comment,function (res) {
$scope.showPosts();
}, function (res) {
console.log("error");
});
};
$scope.likeOrNot = function(id,flag) {
console.log(id,'...',flag);
var postResource = $resource('post/likes/:id/:flag', {id:id,flag:flag}, {save:{method:'GET'}});
postResource.save({id:id,flag:flag},function (res) {
$scope.showPosts();
}, function (res) {
console.log("error");
});
};
$scope.showPosts();
}]);
home.html
<div class="container" style="margin-top: 20px;">
<!-- .comment-list -->
<div class="m-b b-l m-l-md streamline" ng-repeat="item in postList" on-finish-render="ngRepeatFinished">
<div class="post">
<a class="pull-left m-l-n-md">
<div>{
{item.authorName}}</div>
</a>
<div class="m-l-lg panel b-a">
<div class="panel-heading pos-rlt b-b b-light">
<span class="arrow left"></span> <span>{
{item.content}}</span> <label
class="label bg-info m-l-xs" ng-if="item.authorName==username">Delete</label> <span
class="text-muted m-l-sm pull-right"> <i
class="fa fa-clock-o"></i> {
{item.date|date:
'shortTime'}} {
{item.date|date:'mediumDate' }}
</span>
</div>
<div class="panel-body">
<div class="">
{
{item.likes}} <a class="btn btn-default btn-xs" ng-click="likeOrNot(item.id,item.liked=!item.liked)"> <i
class="fa fa-star-o text-muted" ng-if="!item.liked"></i> <i
class="fa fa-star text-danger" ng-if="item.liked"></i> Like
</a> <a class="btn btn-default btn-xs" data-toggle="modal" data-target="#replyModal" ng-click="setReplyPostId(item.id)"> <i
class="fa fa-mail-reply text-muted" ></i>
Reply
</a>
</div>
</div>
</div>
</div>
<!-- .comment-reply -->
<div class="m-l-lg" ng-repeat="cItem in item.commentList">
<a class="pull-left m-l-n-sd">
<div>{
{cItem.cAuthorName}}</div>
</a>
<div class="m-l-xxl panel b-a">
<div class="panel-heading pos-rlt">
<span class="arrow left pull-up"></span> {
{cItem.cContent}} <span
class="text-muted m-l-sm pull-right"> <i
class="fa fa-clock-o"></i> {
{cItem.cDate | date:
'shortTime'}} {
{cItem.cDate | date: 'mediumDate'}}
</span>
</div>
</div>
</div>
</div>
<div class="clearfix m-b-lg">
<div class="m-l-xxl">
<form class="m-b-none">
<div class="input-group">
<input type="text" class="form-control input-lg"
ng-model="post.content" placeholder="Input your post here">
<span class="input-group-btn">
<button class="btn btn-info btn-lg" type="button"
ng-click="addPost()">POST</button>
</span>
</div>
</form>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="replyModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="btn btn-xs" data-dismiss="modal" aria-hidden="true">
cancel
</button>
<button type="button" class="btn btn-warning btn-xs" data-dismiss="modal" aria-hidden="true" style="float:right;" ng-click="addComment()">
send
</button>
</div>
<div class="modal-body">
<input type="text" class="form-control" ng-model="comment.cContent" placeholder="reply sth..."/>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>