最近在学习Angular,所以就想用Angular做一个单页面应用,用了Nosql数据库mongodb,都是最近在学的,所以干脆写一个简单的增删改查,中间集成 的过程不是很顺利,特别是Angular和SpringMVC,所以在这里写出来,共同学习进步。写的这个是简单的 USER的增删改查,只有一个页面,但是有很多的html片段。
在这里介绍一下版本,我使用的是V1.3.9 版本Angularjs +V4.1.3版本的spring + V2.4版本的mongodb+V1.6版本tomcat,使用的是chrome浏览器来调试(推荐使用,当然firefox也不错),使用IDE是Eclipse。
- SpringMVC和Mongodb集成
搭建web项目首先需要把需要的jar包放在lib目录下,加载到web项目中去,由于我没有用maven管理,所以我都放在了WEB-INF/lib目录中,找到相应的jar包后需要配置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_2_5.xsd" id="WebApp_ID" version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>dispater</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispater-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispater</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。contextConfigLocation如果没有配置默认加载的是applicationContext.xml,如果有多个配置文件,需要如上所示加入对应的配置文件。
DispatcherServlet是前置控制器,拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。xml名字需要和配置dispatcherServlet名字相对应,如dispater-servlet.xml。默认会在/WEB-INF/下面查找对应的xml文件,这里也可以显式的配置。
url-pattern 会拦截所有的请求。
接下来看dispater-servlet.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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<mvc:resources location="/resources/" mapping="/resources/**"/>
<context:component-scan base-package="com.mvc" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/pages/"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
SpringMVC会默认拦截所有的请求,这样对于访问一些静态资源来说非常不好,好在Spring提供了配置专门处理静态资源,<mvc:resources location="/resources/" mapping="/resources/**"/>
配置这个以后,把静态资源放入resources中,这样spring就知道这是一个静态资源会有专门的处理器处理,/**表示处理下面的所有资源。配置这个前面需要加上<mvc:annotation-driven/>
。
由于SpringMVC使用了注解去处理,所以使用context:component-scan去扫描相应的包来进行注入和标示。
InternalResourceViewResolver视图解析器,如上定义可以处理 pages/ 下面的jsp资源。(不知道为什么使用.html后缀不能请求让我很郁闷啊)
接下来是applicationContext.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongo" ref="mongo" />
<constructor-arg name="databaseName" value="test" />
</bean>
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
<property name="host" value="localhost" />
<property name="port" value="27017" />
</bean>
<!--启用注解配置 -->
<context:annotation-config />
<context:component-scan base-package="com.mvc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
</beans>
这里就是连接mongodb的配置。唯一需要注意的就是,扫描注解包的时候不要把同一包扫描两次,这样会导致,一些类不能注入,如果需要多个xml文件扫描,需要用到 过滤器context:exclude-filter。
就这样我们就集成了 SpringMVC和mongodb.
2 . Angular与SpringMVC集成
现在需要想办法怎么把angular与SpringMVC集成,由于SpringMVC会拦截所有的请求,根本到不了angular页面,所以需要在 后台做一个控制器转发的主页上。如图
@Controller
@RequestMapping("/")
public class IndexController {
@RequestMapping
public String getIndexPage() {
return "index";
}
}
这样我在pages下定义一个index.jsp页面就可以加载到这个页面了。
我会定义app.js,controllers.js,filter.js,services.js,都引入到 index.jsp页面中,这样当 加载到index页面中的时候,angular就开始起作用了,根据angular 路由来进行页面的跳转
app.js
'use strict'
var app = angular.module('myApp',
['ngRoute',
'userControllers',
'userServices']);
app.config(['$routeProvider',
function($routeProvider){
$routeProvider.when('/user/list',{
templateUrl:'resources/partials/userList.html',
controller:'userListCtrl'
}).when('/user/add',{
templateUrl:'resources/partials/addUser.html',
controller:'userAddCtrl'
}).when('/user/get/:userid',{
templateUrl:'resources/partials/detailUser.html',
controller:'userDetailCtrl'
}).when('/user/update/:userid',{
templateUrl:'resources/partials/updateUser.html',
controller:'userUpdateCtrl'
}).otherwise({
redirectTo:'/user/list'
});
}]);
controllers.js
'use strict'
var myController = angular.module('userControllers',[]);
myController.controller('userListCtrl',['$scope','$location','userservice',
function($scope,$location,userservice){
$scope.users = userservice.list.query();
$scope.delete = function(id,name){
userservice.delete.delete({userid:id});
alert("成功删除用户【"+name+"】");
$location.path('/user/list');
}
$scope.detail = function(id){
$location.path('/user/get/'+id);
}
$scope.edit = function(user){
console.log(user.id);
$location.path('/user/update/'+user.id);
}
}]);
myController.controller('userAddCtrl',['$scope','$location','userservice',
function($scope,$location,userservice){
$scope.save = function(){
userservice.add.save($scope.user);
$location.path('/user/list');
}
$scope.reset = function(){
$scope.user = '';
}
}]);
myController.controller('userDetailCtrl',['$scope','$routeParams','userservice',
function($scope,$routeParams,userservice){
$scope.user = userservice.detail.get({userid:$routeParams.userid});
}]);
myController.controller('userUpdateCtrl',['$scope','$routeParams','$location','userservice',
function($scope,$routeParams,$location,userservice){
console.log("update:"+$routeParams.userid);
$scope.user = userservice.detail.get({userid:$routeParams.userid});
$scope.save = function(){
console.log("update:save");
userservice.update.save($scope.user);
$location.path('/user/list');
}
}]);
services.js
'use strict'
var userServices = angular.module('userServices',['ngResource']);
userServices.factory('userservice',['$resource',
function($resource){
return {
list:$resource('user/list',{},{
query:{method:'GET',params:{},isArray:true}
}),
add:$resource('user/add',{},{
save:{method:'POST'}
}),
delete:$resource('user/delete/:userid',{userid:'@id'},{
delete:{method:'DELETE'}
}),
detail:$resource('user/get/:userid',{userid:'@id'},{
get:{method:'GET'}
}),
update:$resource('user/update',{},{
save:{method:'POST'}
})
}
}]);
由于filter.js中没有写东西就不贴出来了。
使用了bootstrap使界面稍微好看了点。
使用MVC结构,实体类,控制类,服务类
实体类USer
@Document(collection="users")
public class User {
@Id
private String id;
private String sex;
private String name;
private String age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "person[id="+id+",name="+name+",sex="+sex+",age="+age+"]";
}
UserController类
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired(required=true)
@Qualifier("userService")
private UserService service;
@RequestMapping(value="/add",method=RequestMethod.POST)
public String addUser(@RequestBody User user){
System.out.println(user);
service.saveUser(user);
return "index";
}
@RequestMapping(value="/list",method=RequestMethod.GET)
@ResponseBody
public String getAllUser(HttpServletRequest request,HttpServletResponse response){
List<User> list1 = service.getAllUser();
JSONArray jsonarr = JSONArray.fromObject(list1);
return jsonarr.toString();
}
@RequestMapping(value="/delete/{id}",method=RequestMethod.DELETE)
@ResponseBody
public String deleteUser(@PathVariable("id") String id){
System.out.println("删除用户id"+id);
service.deleteUser(id);
return "index";
}
@RequestMapping(value="/get/{id}",method=RequestMethod.GET)
@ResponseBody
public String getUser(@PathVariable("id") String id){
System.out.println("获取用户id"+id);
User user = service.getUser(id);
Gson gson = new Gson();
String userStr = gson.toJson(user);
return userStr;
}
@RequestMapping(value="/update",method=RequestMethod.POST)
@ResponseBody
public String updateUser(@RequestBody User user){
System.out.println("update"+user);
service.updateUser(user);
return "";
}
UserServiceImpl 类
@Component("userService")
public class UserServiceImpl implements UserService{
@Autowired(required=true)
@Qualifier("mongoTemplate")
private MongoTemplate mongoTemplate;
@Override
public void saveUser(User user) {
mongoTemplate.insert(user);
}
@Override
public User getUser(String id) {
return mongoTemplate.findOne(new Query(Criteria.where("id").is(id)), User.class);
}
@Override
public void deleteUser(String id) {
mongoTemplate.findAndRemove(new Query(Criteria.where("id").is(id)), User.class);
}
@Override
public List<User> getAllUser() {
return mongoTemplate.findAll(User.class,"users");
}
@Override
public void createCollection() {
}
@Override
public void dropCollection() {
}
@Override
public void updateUser(User user) {
Criteria criteria = Criteria.where("id").is(user.getId());
Query query = new Query(criteria);
Update update = Update.update("age", user.getAge()).set("name", user.getName()).set("sex", user.getSex());
mongoTemplate.updateFirst(query, update, User.class);
}
需要注意的是,angular中的services.js请求的路径需要与spring controller中的路径对应,services.js中的服务在 controller中去请求。
在页面跳转的时候可以使用$location.path(”);但是我感觉不是很优雅,肯定还有更好的方法,由于我也是初学者没有想到更好的东西,欢迎大家来批评指正。
对于mongodb的安装非常简单,大家可以去官网上下载最新的mongodb,步奏如下
安装配置启动
1.下载解压到D盘根目录,mongodb文件夹,在文件夹下面穿件 data目录,用来存放数据文件,在mongodb目录下建配置文件mongo.config,写入
dbpath=D:\worksoft\mongodb\data
logpath=D:\worksoft\mongodb\logs\mongodb.log
diaglog=3
2.可以将mongodb bin目录配置到 系统变量中,在控制台中使用如下命令启动mongodb服务
mongod.exe –config D:\worksoft\mongodb\mongo.config
3.服务启动后,在另打开一个窗口,使用mongo.exe 命令进入 mongodb命令行模式,默认第一次连接到 test数据库中。
这里我把代码共享到了github上,想要看源码的小伙伴们欢迎来 clone,
这里有源码和jar包,也可以再csdn中下载。
以下是github地址
https://github.com/XiaoDongJi/angularSinglePage.git
csdn下载地址
http://download.csdn.net/detail/u011193139/8441985