前言


AOP在大多数的情况下的应用场景是:日志和验证。至于AOP的理论知识我就不做赘述。而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示。

一、AOP入门


修改“pom.xml”文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.github.carter659</groupId>
<artifactId>spring07</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent> <name>spring07</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

pom.xml

修改入口类文件“App.java”:

package com.github.carter659.spring07;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class App { public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}

App.java

控制器MainController:

package com.github.carter659.spring07;

import java.util.HashMap;
import java.util.Map; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
public class MainController { @GetMapping("/")
public String index() {
return "index";
} @PostMapping("/save")
public @ResponseBody Map<String, Object> save() {
Map<String, Object> map = new HashMap<>();
map.put("msg", "ok");
return map;
}
}

我们拦截控制器中的返回Map的方法。

新建切面类文件“AopAspect.java”:

package com.github.carter659.spring07;

import java.util.HashMap;
import java.util.Map; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component; @Component
@Aspect
public class AopAspect { @Around("execution (java.util.Map com.github.carter659.spring07.MainController.*( .. ) ) ")
public Object invoke(ProceedingJoinPoint point) {
Map<String, Object> map = null;
try {
Object[] args = point.getArgs();
Object val = point.proceed(args);
map = (Map<String, Object>) val;
} catch (Throwable e) {
e.printStackTrace();
map = new HashMap<>();
map.put("msg", e.toString());
}
map.put("aop", "拦截了一个请求");
return map;
}
}

如果能拦截到MainController中的方法,则会在Map中put一对键值。

templates模板:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>玩转spring boot——结合AOP</title>
<script src="//cdn.bootcss.com/angular.js/1.5.6/angular.min.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
var app = angular.module('app', []);
app.controller('MainController', function($rootScope, $scope, $http) {
//保存
$scope.save = function() {
$http({
url : '/save',
method : 'POST'
}).success(function(r) {
$scope.result = JSON.stringify(r)
});
} }); /*]]>*/
</script>
</head>
<body ng-app="app" ng-controller="MainController">
<h1>玩转spring boot——结合AOP</h1>
<h4>
<a href="http://www.cnblogs.com/GoodHelper/">from 刘冬的博客</a>
</h4>
<input type="button" value="调用" ng-click="save()" />
<br />
<h3>调用结果:</h3>
<p>{{result}}</p> <br />
<a href="http://www.cnblogs.com/GoodHelper/">点击访问原版博客</a>
</body>
</html>

index.html

运行效果:

点击调用按钮后:

二、表单验证


  由于有了一节的AOP拦截,那么表单验证就完全可以实现了。但是,spring boot给我们提供了原生的表单验证实例。一些简单的验证,我建议实现spring boot自带的验证,因为它足够简单好用,而复杂的验证可以用AOP来实现。

参考:参考:https://spring.io/guides/gs/validating-form-input/

控制器:

package com.github.carter659.spring07;

import java.util.HashMap;
import java.util.Map; import javax.validation.Valid; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody; /**
* 博客出处:http://www.cnblogs.com/GoodHelper/
*
* @author 刘冬
*
*/
@Controller
public class MainController { @GetMapping("/")
public String index() {
return "index";
} @PostMapping("/save")
public @ResponseBody Map<String, Object> save() {
Map<String, Object> map = new HashMap<>();
map.put("msg", "ok");
return map;
} @PostMapping("/saveOrder")
public @ResponseBody Map<String, Object> saveOrder(@RequestBody @Valid Order order) {
Map<String, Object> map = new HashMap<>();
map.put("msg", "ok");
map.put("order", order);
return map;
}
}

MainController.java

在要验证的方法的参数中增加@Valid注解。

修改Order类:

package com.github.carter659.spring07;

import java.util.Date;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; /**
* 博客出处:http://www.cnblogs.com/GoodHelper/
*
* @author 刘冬
*
*/
public class Order { public String id; @NotNull
@Size(min = 10, max = 20)
public String no; @NotNull
public Date date; @Min(100)
@NotNull
public Integer quantity; /**
* 省略 get set
*/
}

增加这javax.validation.constraints包下的验证注解。

修改index.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>玩转spring boot——结合AOP与表单验证</title>
<script src="//cdn.bootcss.com/angular.js/1.5.6/angular.min.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
var app = angular.module('app', []);
app.controller('MainController', function($rootScope, $scope, $http) { $scope.data = {
no : 'no.1234567890',
date : '2017-01-01',
quantity : 100
}; $scope.errors = {
no : '',
date : '',
quantity : ''
}; //保存
$scope.save = function() {
$http({
url : '/save',
method : 'POST'
}).success(function(r) {
$scope.result = JSON.stringify(r)
});
}
$scope.saveOrder = function() {
$http({
url : '/saveOrder',
method : 'POST',
data : $scope.data
}).success(function(r) {
$scope.result = JSON.stringify(r)
}).error(function(e) {
$scope.result = JSON.stringify(e)
$scope.errors.no = '';
$scope.errors.date = '';
$scope.errors.quantity = '';
for ( var i in e.errors) {
var error = e.errors[i];
var field = $scope.errors[error.field];
if (field == undefined)
continue;
$scope.errors[error.field] = error.defaultMessage;
}
})
}
}); /*]]>*/
</script>
</head>
<body ng-app="app" ng-controller="MainController">
<h1>玩转spring boot——结合AOP与表单验证</h1>
<h4>
<a href="http://www.cnblogs.com/GoodHelper/">from 刘冬的博客</a>
</h4>
<input type="button" value="调用" ng-click="save()" />
<br />
<br />
<input type="button" value="保存订单" ng-click="saveOrder()" />
<br /> 订单信息:
<br />
<table cellspacing="1" style="background-color: #a0c6e5">
<tr>
<td>编号:</td>
<td><input ng-model="data.no" /></td>
<td><font color="red" ng-show="errors.no">{{errors.no}}</font></td>
</tr>
<tr>
<td>日期:</td>
<td><input ng-model="data.date" /></td>
<td><font color="red" ng-show="errors.date">{{errors.date}}</font></td>
</tr>
<tr>
<td>数量:</td>
<td><input ng-model="data.quantity" /></td>
<td><font color="red" ng-show="errors.quantity">{{errors.quantity}}</font></td>
</tr>
</table>
<br />
<h3>调用结果:</h3>
<p>{{result}}</p> <br />
<a href="http://www.cnblogs.com/GoodHelper/">点击访问原版博客</a>
</body>
</html>

index.html

运行效果:

点击“保存订单”按钮:

如果提交的数据未通过验证,会返回400的http请求结果,并会回到AngularJs的http请求的error方法。

我们再对error方法的参数处理,就能实现客户端验证提示。

当表单填写正确后,我们提交请求:

  代码下载:https://github.com/carter659/spring-boot-07.git

如果你觉得我的博客对你有帮助,可以给我点儿打赏,左侧微信,右侧支付宝。

有可能就是你的一点打赏会让我的博客写的更好:)

玩转spring boot系列目录

玩转spring boot——AOP与表单验证的更多相关文章

  1. spring mvc:练习:表单验证(javaConfig配置和注解)

    使用Spring表单标签, 表单验证使用 JSR303 的验证注解,hibernate-validators,提供了使用MessageSource和访问静态资源(如CSS,JavaScript,图片) ...

  2. Spring Boot (一) 校验表单重复提交

    一.前言 在某些情况下,由于网速慢,用户操作有误(连续点击两下提交按钮),页面卡顿等原因,可能会出现表单数据重复提交造成数据库保存多条重复数据. 存在如上问题可以交给前端解决,判断多长时间内不能再次点 ...

  3. 玩转spring boot——开篇

    很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...

  4. Spring Boot 表单验证、AOP统一处理请求日志、单元测试

    一.使用@Valid表单验证 于实体类中添加@Min等注解 @Entity public class Girl { @Id @GeneratedValue private Integer id; pr ...

  5. Spring Boot学习——表单验证

    我觉得表单验证主要是用来防范小白搞乱网站和一些低级的黑客技术.Spring Boot可以使用注解 @Valid 进行表单验证.下面是一个例子. 例子说明:数据库增加一条Student记录,要求学生年龄 ...

  6. Spring Boot 2 + Thymeleaf:服务器端表单验证

    表单验证分为前端验证和服务器端验证.服务器端验证方面,Java提供了主要用于数据验证的JSR 303规范,而Hibernate Validator实现了JSR 303规范.项目依赖加入spring-b ...

  7. Spring Boot笔记八:表单验证

    所谓的表单验证,就是为了防止用户乱输入的,这个问题前端的HTML5就可以判断了,其实不需要后端来验证,这里还是讲一下后端验证 首先,我们的Person类,我们加上一些表单验证的注释,如下: packa ...

  8. spring boot学习(7) SpringBoot 之表单验证

    第一节:SpringBoot 之表单验证@Valid 是spring-data-jpa的功能:   下面是添加学生的信息例子,要求姓名不能为空,年龄大于18岁.   贴下代码吧: Student实体: ...

  9. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

随机推荐

  1. EntityFramework Core Raw SQL

    前言 本节我们来讲讲EF Core中的原始查询,目前在项目中对于简单的查询直接通过EF就可以解决,但是涉及到多表查询时为了一步到位就采用了原始查询的方式进行.下面我们一起来看看. EntityFram ...

  2. 微信小程序体验(2):驴妈妈景区门票即买即游

    驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...

  3. 07. Web大前端时代之:HTML5+CSS3入门系列~H5 地理位置

    Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 源码:https://github.com/duniti ...

  4. 视频 - 在 VirtualBox 中部署 OpenStack

    大家新年好,CloudMan 今天给大家带来一件新年礼物. 一直以来大家都反馈 OpenStack 学习有两大障碍:1. 实验环境难搭2. 体系复杂,难道大今天我就先帮大家解决环境问题.前两天我抽空在 ...

  5. 如何使用swing创建一个BeatBox

    首先,我们需要回顾一些内容(2017-01-04 14:32:14): 1.Swing组件 Swing的组件(component,或者称之为元件),是较widget更为正确的术语,它们就是会放在GUI ...

  6. 【干货分享】流程DEMO-借款申请

    流程名: 借款申请   业务描述: 当员工个人在工作中需要进行借款时,通过此项流程提交借款申请,审批通过后,财务部进行款项支付.   流程相关文件: 流程包.xml WebService业务服务.xm ...

  7. Web开发安全之文件上传安全

    很长一段时间像我这种菜鸡搞一个网站第一时间反应就是找上传,找上传.借此机会把文件上传的安全问题总结一下. 首先看一下DVWA给出的Impossible级别的完整代码: <?php if( iss ...

  8. Android开发学习——动画

    帧动画> 一张张图片不断的切换,形成动画效果* 在drawable目录下定义xml文件,子节点为animation-list,在这里定义要显示的图片和每张图片的显示时长              ...

  9. DevOps对于企业IT的价值

    其实从敏捷延展开的 DevOps 概念很早就已经被提出,不过由于配套的技术成熟度水平层次不齐, DevOps 的价值一直没有有效地发挥出来.现如今,随着容器技术的发展, DevOps 在企业中的实践难 ...

  10. windows 7(32/64位)GHO安装指南(系统安装篇)~重点哦!!~~~~

    经过了前三篇的铺垫,我们终于来到了最重要的部分~~如果没看过前几篇的小伙伴们,可以出门右转~~用十几分钟回顾一下~~然后在看这篇会感觉不一样的~~~~ 下面让我们来正式开始吧 我们进入大白菜的桌面是酱 ...