1. 程式人生 > >Maven + Spring MVC+Mybatis + MySQL +AngularJS + Bootstrap 實現簡單微博應用(三)前後臺互動

Maven + Spring MVC+Mybatis + MySQL +AngularJS + Bootstrap 實現簡單微博應用(三)前後臺互動

上一節http://blog.csdn.net/shymi1991/article/details/51985371

該章節實現實現使用者註冊、登入、發表微博、評論微博等功能。

1. 配置檔案

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

封裝響應資料

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. 前端框架


該工程的前端引用了angularJS庫、bootstrap庫和jquery庫(因為bootstrap依賴jquery)。我們重點關注的是js資料夾下的與本專案邏輯直接相關的js檔案。

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 依賴注入、配置路由
'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設定、讀取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 使用者註冊


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 使用者登入


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 主介面


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>
專案程式碼地址 https://github.com/sommer1991/javaWeb.git