SpringBoot初体验(续)
1.如果你还不知道SpringBoot的厉害之处,或者你不知道SpringBoot的初级用法,请移步我的上一篇文章,传送门
2.SpringBoot中的表单验证
所谓验证,无非就是检验,对比,正如javax.validation.constraints包中的各种注解,从名字上我们可以看出来:

我就用这个包中的Min做例子:
我给我们的数据持久化层Dril类的age属性加上注解@Min
a.Dril.java
//数据持久化
@Entity
public class Dril { @Id
@GeneratedValue
private Integer id; private String name; @Min(value=18,message="未成年!")
private Integer age; public Dril() { } public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} }
b.DrilController.java
@RequestMapping(value="addDril.do",method=RequestMethod.POST)
public Dril getDrilName(@Valid Dril dril,BindingResult bindingResult){ if (bindingResult.hasErrors()) {
logger.info(bindingResult.getFieldError().getDefaultMessage());
return null;
}
return drilService2.addDril(dril);
c.运行结果
当我们插入age小于18的数据的时候出现

console输出:

如果我们输入的对象年龄大于18的话出现

其他方法自行测试。
2.AOP统一处理请求日志
a.简单介绍AOP
面向对象将对象垂直划分,并且每个都有自己的方法,AOP将面向对象的庞大体系进行水平分割,并将影响到多个类的公共行为做成可重用的模块。正如AOP的核心思想,将通用逻辑从业务逻辑分离出来。
b.AOP的运用场景
权限控制,缓存控制,事务控制,审计日志,性能监控,分布式追踪,异常处理
b.使用Aspectj注解
@Aspect:用于声明当前类是一个切面
@Pointcut:用于描述在哪些类、哪些方法上执行切面的代码
Advice:描述想要在这些方法执行的什么时机进行拦截
在介绍5种Advice之前,我先说说切面表达式
c.切面表达式
1.designators(指示器)
描述通过什么样的方式去匹配哪些类、哪些方法。如匹配方法 execution(),匹配注解 @target() @args() @within() @annotation(),匹配包/类型 @within(),匹配对象 this() bean()target(),匹配参数 args()。
2.wildcards(通配符)
* .. +
使用通配符进行描述,如* 匹配任意数量的字符 ,+ 匹配指定类及其子类, .. 一般用于匹配任意参数的子包或参数
3.operators(运算符)
&& || !
使用运算符进行多条件的判断,如&& 与操作符, || 或操作符 ,! 非操作符
d.5种advice1.匹配包类
// 匹配 ProductServiceAop 类里面的所有方法
@Pointcut("within(com.myimooc.springaopguide.service.ProductServiceAop)") public void matchType(){
}
// 匹配 com.myimooc.springaopguide.service 包及子包下所有类的方法
@Pointcut("within(com.myimooc.springaopguide.service..*)")
public void matchPackage(){
}
2.匹配对象
// 匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法
@Pointcut("this(com.myimooc.springaopguide.dao.DemoDao)")
public void testDemo() {
}
// 匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法
@Pointcut("target(com.myimooc.springaopguide.dao.IDao)")
public void targetDemo() {
}
// 匹配所有以Service结尾的bean里面的方法
@Pointcut("bean(*Service)")
public void beanDemo() {
}
3.匹配参数
// 匹配任何以find开头而且只有一个Long参数的方法
@Pointcut("execution(* *..find*(Long))")
public void argsDemo1(){}
// 匹配任何只有一个Long参数的方法
@Pointcut("args(Long)")
public void argsDemo2(){}
// 匹配任何以find开头而且第一个参数为Long型的方法
@Pointcut("execution(* *..find*(Long,..))") public void argsDemo3(){}
// 匹配第一个参数为Long型的方法
@Pointcut("args(Long,..))")
public void argsDemo4(){}
4.匹配注解
// 匹配方法标注有AdminOnly的注解的方法
@Pointcut("@annotation(com.myimooc.springaopguide.security.AdminOnly)") public void annoDemo(){
}
// 匹配标注有Beta的类底下的方法,要求的annotation的RetentionPolicy级别为CLASS @Pointcut("@within(com.google.common.annotations.Beta)")
public void annoWithDemo(){
}
// 匹配标注有Repository的类底下的方法,要求的RetentionPolicy级别为RUNTIME @Pointcut("@target(org.springframework.stereotype.Repository)")
public void annoTargetDemo(){
}
// 匹配传入的参数类标注有Repository注解的方法
@Pointcut("@args(org.springframework.stereotype.Repository)")
public void annoArgsDemo(){
}
5.匹配方法
execution()格式
execution(
modifier-pattern? // 修饰符匹配
ret-type-pattern // 返回值匹配
declaring-type-pattern? // 描述值包名
name-pattern(param-pattern) // 方法名匹配(参数匹配)
throws-pattern?// 抛出异常匹配
)
实例:
/**
* 切点
* 使用public修饰符匹配,任意返回值,在com.huhu.controller包下以Controller结尾的类名下的getDrils()方法
*/
@Pointcut("execution(public * com.huhu.controller..*Controller.getDrils(..))")
public void Log() { }
e.AOP所需要的注解
@Before,前置通知
@After(finally)后置通知,方法执行完之后
@AfterReturning,返回通知,成功执行之后
@AfterThrowing,异常通知,抛出异常之后
@Around,环绕通知
f.请开始我们的表演
代码接着上篇的代码,我们给在controller运行前输出访问的URL,METHOD,IP,类方法以及参数
HttpAspect.java
@Aspect
@Component
public class HttpAspect {
Logger logger=LoggerFactory.getLogger(HttpAspect.class); /**
* 切点
* 使用public修饰符匹配,任意返回值,在com.huhu.controller包下以Controller结尾的类名下的getDrils()方法
*/
@Pointcut("execution(public * com.huhu.controller..*Controller.getDrils(..))")
public void Log() { } /**
* 用于匹配方法执行的连接点
* @param joinpoint(为org.aspectj.lang.JoinPoint的对象)
*/
@Before("Log()")
public void before(JoinPoint joinpoint) {
logger.info("AOP的before()方法"); ServletRequestAttributes attributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url
logger.info("url={}",request.getRequestURL());
//method
logger.info("method={}",request.getMethod());
//ip
logger.info("ip={}",request.getRemoteAddr());
//类方法
logger.info("class_method= {}",joinpoint.getSignature().getDeclaringTypeName()+"."+joinpoint.getSignature().getName());
//参数
logger.info("args={}",joinpoint.getArgs());
} @After("Log()")
public void after() {
logger.info("AOP的after()方法");
}
}
为了知道是运行controller前输出的,我们给controller加上
@RequestMapping(value="getDrils",method=RequestMethod.GET)
public List<Dril> getDrils(){
logger.info("getDrils");
List<Dril> drils =drilService.findAll();
return drils;
}
运行结果:

结果向我们展示了使用AOP的结果,所以AOP显然能做权限控制,缓存控制,事务控制,审计日志,性能监控,分布式追踪,异常处理这些事了。
参考资料:
慕课网--Spring Boot进阶之Web进阶
SpringBoot初体验(续)的更多相关文章
- SpringBoot初体验及原理解析
一.前言 上篇文章,我们聊到了SpringBoot得以实现的幕后推手,这次我们来用SpringBoot开始HelloWorld之旅.SpringBoot是Spring框架对“约定大于配置(Conv ...
- SpringBoot初体验之整合SpringMVC
作为开发人员,大家都知道,SpringBoot是基于Spring4.0设计的,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程.另外Spr ...
- SpringBoot初体验
1.elipse中创建Springboot项目并启动 具体创建步骤请参考:Eclipse中创建新的Spring Boot项目 2.项目的属性配置 a.首先我们在项目的resources目录下appli ...
- SpringBoot 初体验
1.Spring Boot 简介 简化Spring应用开发的一个框架 整个Spring技术栈的一个大整合 J2EE开发的一站式解决方案 2.微服务 2014, martin fowler 微服务:架构 ...
- springboot初体验-不知道怎么创建spring-boot项目?
https://spring.io/projects/spring-boot/ 在以上地址找到 Quick start Bootstrap your application with Spring I ...
- (一)SpringBoot基础篇- 介绍及HelloWorld初体验
1.SpringBoot介绍: 根据官方SpringBoot文档描述,BUILD ANYTHING WITH SPRING BOOT (用SPRING BOOT构建任何东西,很牛X呀!),下面是官方文 ...
- (一)SpringBoot2.0基础篇- 介绍及HelloWorld初体验
1.SpringBoot介绍: 根据官方SpringBoot文档描述,BUILD ANYTHING WITH SPRING BOOT (用SPRING BOOT构建任何东西,很牛X呀!),下面是官方文 ...
- springboot+支付宝完成秒杀项目的初体验
springboot+支付宝完成秒杀项目的初体验 思考的问题: 首先是秒杀的商品查询,考虑到是热点数据,所以写一个接口读取当日批次的秒杀商品到redis中(那么接下来对商品的操作都放入redis中). ...
- ipython及Python初体验
阅读目录: Python环境体验 Python编辑器 ipython安装 Python提示符 Python初体验 print和变量 变量操作 内建函数:方法 数学运算:简单算术.随机数 关于模块 一. ...
随机推荐
- Java 删除项目中的.svn信息
有时候拿过来的war包或者源代码中有.svn信息,我们想删除掉它,然后再上传到自己的svn中. 我这里是自己写的java代码实现的. package com.bstek.transit; import ...
- JVM菜鸟进阶高手之路十二(jdk9、JVM方面变化, 蹭热度)
转载请注明原创出处,谢谢! 经过 4 次跳票,历经曲折的 Java 9 正式版终于发布了!今天看着到处都是jdk9发布了,新特性说明,心想这么好的蹭热度计划能错过嘛,哈哈,所以就发了这篇文章. 目前j ...
- 关于Visio Studio 2012使用Nuget获取Sqlite驱动包报错:“System.Data.SQLite.EF6”的架构版本与 NuGet 的版本 2.0.30625.9003 不兼容
背景 笔者的VS2012版本比较老旧,是几年以前下载的.平时添加三方包和驱动包都是手动添加.后来了解到有Nuget这个工具,如获至宝.可是在使用过程中却出了不少问题. 最初,笔者尝试使用Nuget添加 ...
- 【设计模式】module(模块)模式
写在前面 最近刚接触到设计模式, <head first设计模式>里有一篇文章,是说使用模式的心智, 1.初学者"心智" :"我要为HELLO WORLD找个 ...
- ng-options的使用
参考:官方文档.zhx1991 select 无默认选择一项 <select name="" id="" class="form-control ...
- Servlet学习应该注意的几点
一.Servlet生命周期(即运行过程) (1)初始阶段,调用init()方法 (2)响应客户请求阶段,调用service()方法.由service()方法根据提交方式不同执行doGet()或doPo ...
- Codeforces Round #436 (Div. 2) C. Bus
http://codeforces.com/contest/864/problem/C 题意: 坐标轴上有x = 0和 x = a两点,汽车从0到a之后掉头返回,从a到0之后又掉头驶向a...从0到a ...
- 变量的声明和定义以及extern的用法
变量的声明和定义以及extern的用法 变量的声明不同于变量的定义,这一点往往容易让人混淆. l 变量 ...
- 表空间tablespace,数据文件datafiles,和控制文件control files介绍
https://docs.oracle.com/cd/B19306_01/server.102/b14220/physical.htm#i5919 本文系翻译 表空间tablespace,数据文件da ...
- 学习札记 ----wind7下如何安装SqlServer数据库
1.控制面板 ---找到程序和功能选项 如下图所示: 2.打开程序和功能后进入如下图所示的界面,点击打开或关闭window功能. 3.启动window7自带的IIS功能.如下图所示: 4.如上动作准备 ...