Maven + Spring MVC+Mybatis + MySQL +AngularJS + Bootstrap 實現簡單微博應用(三)前後臺互動
阿新 • • 發佈:2019-02-04
上一節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