// 建立模块
var app=angular.module("pingyougou",["pagination"]);
// 创建控制器,数据交互需要传入scope和http参数
app.controller("brandController",function ($scope,$http)
<!--定义模块名称,指定控制器,ng-init="findPage()"在分页插件使用后就不需要调用-->
<body class="hold-transition skin-red sidebar-mini"
ng-app="pingyougou" ng-controller="brandController" >
<!--新建按钮中添加属性 ng-click="newBrand={}"使每次新建之后再次点击时数据清空-->
ng-click="deleteChecks()" 给一个按钮绑定点击事件,点击之后执行方法,可传参数
ng-click="getchecks($event,fdres.id)" 删除操作中的,给checkbox添加的属性
<!--分页插件使用 在要展示分页的地方写入-->
<tm-pagination conf="paginationConf"></tm-pagination>
<!-- 给一个input框添加属性,表示输入的值存到改model中,利于传输给后台操作-->
<input class="form-control" placeholder="品牌名称" ng-model="newBrand.name">
对于post请求时,后台接收需要使用@RequestBody,并且前端传值使用 $scope.searchEx
@RequestBody TbBrand tb,Integer pageNum, Integer pageSize
对于get请求的时候 后台接收就不需要使用@RequestBody,传值时,参数直接拼接在路径上
<!--引入分页插件-->
<!--开始-->
<script src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!--结束-->
<!--分页插件使用 写在分页条要显示的地方-->
<tm-pagination conf="paginationConf"></tm-pagination>
// 分页插件展示,
$scope.paginationConf={
currentPage:1, // 当前页码数
totalItems:10, // 总记录数
itemsPerPage:10, // 每页记录数
perPageOptions:[5,10,20,30,40,50], // 每页选择显示条数
onChange:function () {
// 当页码重新变更后自动触发的方法
$scope.reloadList(); // 重新加载
}
};
// 刷新方法,简单的封装一下
$scope.reloadList=function () {
// 给search()传入值,直接取代findPage()方法 ,
$scope.search($scope.paginationConf.currentPage , $scope.paginationConf.itemsPerPage );
};
- service.js中分页配置 及条件查询,处理400错误,非空优化问题
// 条件分页展示,传入参数
// 设置一个初始化值,没有属性值的对象,
// 解决最开始时搜索框中没有数据的情况,否则他是null,就会报错400(传入的参数对象为null),
$scope.searchEx={};
$scope.search = function (pageNum, pageSize) {
// 发起请求传入参数,获取数据,返回结果pageBeansexs(json格式的)
$http.post("../brand/search.do?pageNum=" + pageNum
+ "&pageSize=" + pageSize , $scope.searchEx).success(
function (pageBeansexs) {
// 将返回的结果中的rows属性交给list
$scope.list = pageBeansexs.rows;
// 将返回的结果PageBeans中的总记录数totals属性交给paginationConf
$scope.paginationConf.totalItems = pageBeansexs.totals;
})
};
d. serviceImpl的分页编写
// 开启分页插件
PageHelper.startPage(pageNum,pageSize);
// 获取条件
TbBrandExample exap = new TbBrandExample();
// 通过TbBrandExample方法获取Criteria对象,其中封装了条件查询的方法
Criteria criteria = exap.createCriteria();
// 传条件,封装对象
// 为了处理后台条件最开始为空的情况,空值查不到数据报错,实行非空判断(优化)
if(tb!=null){
// 不等于空的时候才添加条件
// 都为空时,就exap=null,就不影响查询所有
if(tb.getName()!=null&tb.getName()!=""){
criteria.andNameLike("%"+tb.getName()+"%");
}
if(tb.getFirstChar()!=null&tb.getFirstChar()!=""){
criteria.andFirstCharLike("%"+tb.getFirstChar()+"%");
}
}
// 用Page<TbBrand>接收数据 条件查询
Page<TbBrand> page =(Page<TbBrand>) brandMapper.selectByExample(exap);
// long强转为int
int total =(int) page.getTotal();
// 每页的记录
List<TbBrand> rows = page.getResult();
// 封装到PageBeans中返回
return new PageBeans(total,rows);
f. controller 中的分页配置
@RequestMapping("/search")
// 条件查询,前端post请求传入一个对象tb,和页码数
public PageBeans search(@RequestBody TbBrand tb,Integer pageNum, Integer pageSize){
return brandService.search(tb,pageNum, pageSize);
}
<!--这3个是select2的原生js框架-->
<link rel="stylesheet" href="../plugins/select2/select2.css" />
<link rel="stylesheet" href="../plugins/select2/select2-bootstrap.css" />
<script src="../plugins/select2/select2.min.js" type="text/javascript"></script>
<!--这个必须引在angular.min.js的下面才生效,由于要在使用分页 还需要在base_pagination.js下面-->
<script type="text/javascript" src="../js/angular-select2.js"></script>
<td>关联品牌</td>
<!--select2这是一个下拉框 select2-model把选择的数据提交到这里 congfig数据来源
multiple 表示多选,不然就是单选
-->
<td>
<input select2 select2-model="entity.brandIds" config="brandList"
multiple placeholder="可选多个品牌" class="form-control" type="text"/>
</td>
//初始化一个 brandList$scope.brandList={data:[]}; // 使用brandService查找brand列表集合的方法,要导入brandService.js// 让他在页面加载的时候就执行,ng-init$scope.findBrandList=function () { brandService.selectBrandList().success( function (selcetBrListResponse) { // 给$scope.brandList赋值,返回的就是brand的Map列表 $scope.brandList={data:selcetBrListResponse}; } ); }
<properties>
// 版本锁定
<spring.version>4.2.4.RELEASE</spring.version>
</properties>
<dependencies>
// spring的jar坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
// springSecurity的jar配置
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
// servlet的依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
// spring-security.xml的监听
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!--过滤器 springSecurity的入口 -->
<filter>
// springSecurityFilterChain名字固定,内置,后台要用,不可该
<filter-name>springSecurityFilterChain</filter-name>
// 代理过滤配置,拦截请求到这里,然后去找springSecurityFilterChain
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!--设置中文编码解决问题-->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
// 拦截所有请求
<url-pattern>/*</url-pattern>
</filter-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
// 添加dubbo的注入需要
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
// 添加dubbo的注入需要
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<!--过滤 哪些路径访问不拦截-->
<http pattern="/*.html" security="none"></http>
<http pattern="/css/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/plugins/**" security="none"></http>
<!--设置注册不被拦截-->
<http pattern="/seller/add.do" security="none"></http>
<!-- 配置拦截规则
use-expressions="false"表示是否开启SPEL表达式,适用于多个角色,
更简便,默认值为true-->
<http use-expressions="false">
<!-- 当前用户必须拥有该角色,才能访问根目录及其子目录的所有资源 -->
<intercept-url pattern="/**" access="ROLE_SELLER"/>
<!--<intercept-url pattern="/**" access="hasRole('ROLE_SELLER')"/>
如果use-expressions="true" 则需要这么写,单个角色可以这么写,简单-->
<!--开启表单登录功能-->
<!--login-page 自定义的登陆界面
default-target-url 默认登录成功后的跳转页面
authentication-failure-url 登录失败的跳转页面
always-use-default-target 只要是登陆就默认跳转到登陆页面,
解决了在直接访问其他页面(如访问品牌管理)时,
再登录后进入的是其他页面,而不是首页的问题 -->
<form-login
login-page="/shoplogin.html"
default-target-url="/admin/index.html"
authentication-failure-url="/shoplogin.html"
always-use-default-target="true"/>
<!--csrf跨站请求伪造 ,true 关闭csrf 如果时jsp页面就不需要-->
<csrf disabled="true"/>
<!--配置头信息框架使用-->
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
<!--退出 logout-success-url推出后默认跳转页面-->
<logout logout-success-url="/shoplogin.html"/>
</http>
<!--认证管理器-->
<authentication-manager>
<!--调用userDtiles这个类,来获取用户的访问权限权限-->
<authentication-provider user-service-ref="userDtiles">
<!--登录引入密码加密-->
<password-encoder ref="passwordEncoder"></password-encoder>
<!-- <user-service > 用户信息写死的情况
authorities用户属于哪个角色
<user name="admin" password="123456" authorities="ROLE_SELLER"/>
<user name="zhangsan" password="123456" authorities="ROLE_SELLER"/>
</user-service>-->
</authentication-provider>
</authentication-manager>
<!--引入userDtiles这个继承的Java类-->
<beans:bean id="userDtiles" class="com.pinyougou.shop.secuservice.UserDtiles">
<!--xml的set注入sellerService这个bean-->
<beans:property name="sellerService" ref="sellerService"></beans:property>
</beans:bean>
<!--通过dubbo获取这个bean-->
<dubbo:application name="pinyougou-shop-web" />
<dubbo:registry address="zookeeper://192.168.25.128:2181"/>
<!--直接导入接口-->
<dubbo:reference id="sellerService" interface="com.pinyougou.sellergoods.service.SellerService">
</dubbo:reference>
<!--创建BCryptPasswordEncoder对象bean,-->
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></beans:bean>
</beans:beans>
// 认证类,用于读取数据库的user信息,必须要继承UserDetailsService这个接口
public class UserDtiles implements UserDetailsService{
// 使用xml配置的set方式注入这个类,因为只有一个减少初始化时的消耗
private SellerService sellerService;
public void setSellerService(SellerService sellerService) {
this.sellerService = sellerService;
}
// 重写接口方法
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//构建角色列表
List<GrantedAuthority> grantAuths = new ArrayList<>();
// 匿名内部类增加角色权限
grantAuths.add(new SimpleGrantedAuthority("ROLE_SELLER"));
// 查询数据库并返回符合要求(审核过的)的用户
TbSeller seller = sellerService.findOne(username);
if(seller!=null){
// 通过审核才过,
if(seller.getStatus().equals("1")){
// 状态为1,审核通过
return new User(username,seller.getPassword(),grantAuths);
}
return null;
}else {
return null;
}
}
}
@RequestMapping("/add")
public ResultMessage add(@RequestBody TbSeller seller){
// new一个加密对象,
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder();
// 密码储存加密操作
String encode = bpe.encode(seller.getPassword());
seller.setPassword(encode);
try {
sellerService.add(seller);
return new ResultMessage(true, "增加成功");
} catch (Exception e) {
e.printStackTrace();
return new ResultMessage(false, "增加失败");
}
}
<!--action跳转的时serurity提供的登陆路径,
可以在xml中路径配置中改 login-processing-url =""
method必须时post,username也可以改 但没必要-->
<form class="sui-form" action="/login" method="post" id="loginform">
......
<div class="logined">
<!--属性target="_blank" 失败跳转到新的页面时,会跳转到新的窗口-->
<!--onclick="document:loginform.submit()" 提交表单-->
<a class="sui-btn btn-block btn-xlarge btn-danger"
>登 录</a>
</div>
<div class="pull-right">
<!-- 框架提供的注销方式,配置有注销跳转页面 -->
<a href="../logout" class="btn btn-default btn-flat">注销</a>
</div>
app.controller("indexController",function ($scope,$controller,loginService) {
// 继承通用controller
$controller("baseController",{$scope:$scope});
// 获取用户名的方法
$scope.getName=function () {
loginService.getName().success(
// 返回一个map集合
function (nameResponse) {
// 赋值给展示到页面的变量
$scope.usname=nameResponse.userName;
})
};
});
app.service("loginService",function ($http) {
// 页面获取用户名的方法
this.getName=function () {
return $http.get("/login/getName.do");
}
});
@RestController
@RequestMapping("/login")
public class LoginController {
@RequestMapping("/getName")
public Map getName(){
HashMap map = new HashMap<>();
// 通过security框架来获取域中的用户name,用以后续使用
String name = SecurityContextHolder.getContext().getAuthentication().getName();
// 项map中添加数据
map.put("userName",name);
// 返回包含name数据的map集合,
return map;
}
}
ng-init="getName()"{{usname}}
|
|