虽然学习完了ssm框架,也敲完练习了一边,但是内容有点多,这里先写一些梳理和注意事项
AOPxml方式
public class Logger {
public void before(){
System.out.println("before方法执行了!!");
}
}
public interface UserAop {
void findAll();
}
public class UserAopImpl implements UserAop {
@Override
public void findAll() {
System.out.println("findALL执行了!!!");
}
}
<bean class="com.zjf.log.Logger" id="logger"/>
<bean class="com.zjf.service.impl.UserAopImpl" id="userAop"/>
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.zjf.service.impl.UserAopImpl.*(..))"/>
<aop:aspect ref="logger">
<aop:before method="before" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
AOP注解方式
<context:component-scan base-package="com.zjf"/>
<aop:aspectj-autoproxy/>
@Component
@Aspect
public class Logger {
@Around("execution(* com.zjf.service.impl.UserAopImpl.findAll(..))")
public Object aroundMethod(ProceedingJoinPoint point){
Object obj=null;
System.out.println("进入方法!!!");
try {
obj = point.proceed();
System.out.println("执行完毕!!!");
} catch (Throwable throwable) {
System.out.println("出现异常!!");
}finally {
System.out.println("方法运行完毕!!");
}
return obj;
}
}
Spring事务控制xml
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
<tx:method name="find" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.zjf.service.impl.UserAopImpl.findAll(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
Spring事务控制注解版
<tx:annotation-driven transaction-manager="transactionManager"/>
@Service
@Transactional
public class UserAopImpl implements UserAop {
@Override
public void findAll() {
System.out.println("findALL执行了!!!");
}
}
SpringMVC几个重要注解
@ResponeBody将java对象转为json格式
@DateTimeFormat(pattern=“yyyy-MM-dd”)
//Converter<String,Date>: 它提供了字符串与日期格式转换的方法。
// 范型参数1:表示用户提交的类型 范型参数2:表示转换后的结果类型
public class DateConverter implements Converter<String,Date> {
//日期转换的方法
//参数是用户提交的数据
//返回值是转换后的结果
public Date convert(String s) {
try {
return new SimpleDateFormat("yyyy-MM-dd").parse(s);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
<!--配置类型转换器-->
<bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
<!--此工厂类可能加载多个配置类,所以converters参数是set集合类型-->
<property name="converters">
<set>
<bean class="com.itheima.converter.DateConverter"/>
</set>
</property>
</bean>
文件上传
<!--配置文件上传组件: id的值不能随便写,必须是multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置单次文件上传的大小. 单位是byte 1M=1024kb 1kb=1024byte 10M= 10*1024*1024byte-->
<property name="maxUploadSize" value="10485760"/>
</bean>
//文件上传
@RequestMapping("/demo10")
@ResponseBody
public String demo10(MultipartFile picture) throws IOException {
System.out.println("文件名:"+picture.getOriginalFilename());
//System.out.println("文件流:"+picture.getInputStream());
picture.transferTo(new File("d:/upload/"+ UUID.randomUUID().toString()+picture.getOriginalFilename()));
return "OK";
}
面试题:
文件上传对表单的3个要求:
1、请求方式必须是post。 method=“post”
2、enctype的值必须是"multipart/form-data" enctype:encoding type
3、必须编写文件域
@RequestParam 1.获取集合类型参数2.匹配前端传来的参数3.设置默认值
@RequestBody 用来接收前端传来的json格式
@ControllerAdvice 标注在类上,声明当前类是一个用于专门处理异常的类
@ExceptionHandler 标注在方法上,声明当前方法可以处理哪些异常如:@ExceptionHandler(Exception.class)
@RestController=@Controller+@ResponseBody
@PostMapping=@ReqestMapping(value=“/user”,method=RequestMethod.POST)
@Getxx、@Deletexx、@Putxx
@PathVariable:在Restful风格中用来匹配前端来的参数如:@GetMapping(“/user/{id}”)—>(@PathVariable(“id”) String id)
统一异常处理
//统一异常处理类
@ControllerAdvice //此注解声明在类上,声明当前类是一个用于处理异常的切面类
public class CommonExceptionHandler {
//异常处理方法
@ExceptionHandler(Exception.class)
@ResponseBody
public ResultInfo handlerException(Exception e){
e.getMessage();
return new ResultInfo("500", "网络错误,请稍后再试");
}
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public ResultInfo handlerNullPointerException(Exception e){
e.getMessage();
return new ResultInfo("501", "网络错误,请稍后再试");
}
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public ResultInfo handlerArithmeticException(Exception e){
e.getMessage();
return new ResultInfo("502", "网络错误,请稍后再试");
}
}
自定义拦截器
需导入:javax.servlet.servlet-api <scope>provided</scope>
public class MyInterceptor1 implements HandlerInterceptor {
//进入Controller方法之前执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("请求到达了Controller方法之前");
return true; //返回true,则向后继续执行(放行),否则会截断向后执行
}
//在Controller方法执行之后执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("请求在Controller方法之后执行了");
}
//即将离开服务器
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("即将离开服务器");
}
}
<!--配置拦截器: 在此标签中可以配置多个拦截器-->
<mvc:interceptors>
<!--配置一个拦截器-->
<mvc:interceptor>
<!--
/** 表示所有深度的路径,包含一些静态资源css js html
-->
<!--<mvc:mapping path="/**"/>-->
<mvc:mapping path="/user/*"/>
<!--表示哪个路径不拦截-->
<mvc:exclude-mapping path="/user/demo16"/>
<mvc:exclude-mapping path="/user/demo15"/>
<!--如果路径匹配到了,则会执行此类中的方法,否则直接进入目标方法-->
<bean class="com.itheima.web.interceptor.MyInterceptor1"/>
</mvc:interceptor>
<mvc:interceptor>
<!--<mvc:mapping path="/**"/>-->
<mvc:mapping path="/user/*"/>
<!--表示哪个路径不拦截-->
<mvc:exclude-mapping path="/user/demo16"/>
<mvc:exclude-mapping path="/user/demo15"/>
<bean class="com.itheima.web.interceptor.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
Restful风格
原来 | Restful | |
---|---|---|
保存 | /saveUser | POST /user |
修改 | /updateUser | PUT /user |
删除 | /deleteUser?id=1 | DELETE /user/1 |
查询所有 | /findAllUser | GET /user |
查询一个 | /findByUserId?id=1 | GET /user/1 |
get delete 是没有请求体 post put 有请求体
前后端分离后,那么即使前后端相互不交流怎么方便交互呢?
那么这里就需要一些规范了,包括统一的接口,统一的javabean等等,如下我介绍一种公司常用的方式!!
统一结果的类
//通用返回结果,服务端响应的数据最终都会封装成此对象
//导入统一结果的类
@Data
public class ResultInfo implements Serializable {
private Integer code; //编码:1成功,0和其它数字为失败
private String msg; //错误信息
private Object data; //数据
//成功结果
public static ResultInfo success(Object object) {
ResultInfo resultInfo = new ResultInfo();
resultInfo.data = object;
resultInfo.code = 1;
return resultInfo;
}
//失败结果
public static ResultInfo error(String msg) {
ResultInfo resultInfo = new ResultInfo();
resultInfo.msg = msg;
resultInfo.code = 0;
return resultInfo;
}
}
使用方法如下:
例如前端给后端发来一个ajax请求
//根据number查询学生信息 /student/001
findByNumber(number) {
axios.get('/student/' + number).then(resp => {
//此处先省略!看后面
})
},
后端只需知道发来的url,通过如下代码查询完结果后,返回一个json格式
//这里使用了restful编程风格,这是公司的主流!!
@GetMapping("/student/{number}")
public ResultInfo findByNumber(@PathVariable("number") String number){
Student student = studentService.findByNumber(number);
return ResultInfo.success(student);
}
//JSON数据格式:
//{code: 1, msg: null, data: {number: "hm003", name: "王五", birthday: "1985-06-19", address: "上海"}}
那么前端可以不用管后端发送的啥,反正是查询成功的结果可以直接写
student: {};
findByNumber(number) {
axios.get('/student/' + number).then(resp => {
if (resp.data.code == "1") {
this.student = resp.data.data;
}
})
}
这样是前后端统一规范,即使前端看不见后端的代码,后端看不见前端的代码也可以完成交互