每日学Java之一万个为什么
文章目录
- RESTFUL 风格设计
- JSON数据中的返回工具类 R
- 浏览器跨域问题及其前后端解决办法
- SpringMVC基于AOP的功能有哪些
- SpringMVC声明式异常处理
- SpringMVC拦截器 区别filter不能放行
RESTFUL 风格设计
- url:尽量使用名词,如果实在重复使用动词
- method:GET DELET(区别路径传参:唯一标识,和接受查询字符串:范围查询)POST PUT
- param:
- response:json
简单示例:
| 接口 | 保存用户功能 | id查询 | id更新 | id删除 | 多条件模糊查询 | 数据分页展示 |
| ------------ | ------------- | ---------- | ------------- | ------------- | ---------------------------------------------- | :----------------------------------------------------------: |
| **USER** | /user | /user/{id} | /user | /user/{id} | /user/search?page={page}&size={size}&keyword{} | /user?page={page}&size={size} |
| **METHOD** | post | get | put | delete | get | get |
| **PARAM** | json | path | json | path | page size keyword | page,size |
| **RESPONSE** | json{message} | json{id} | json{message} | json{message} | json:{user} | json{`content` `totalElements` `totalPages`: `number`: `size`: `first`: `last`: } |
JSON数据中的返回工具类 R
package com.atguigu.utils;
/**
* projectName: com.atguigu.utils
*
* description: 返回结果类
*/
public class R {
private int code = 200; //200成功状态码
private boolean flag = true; //返回状态
private Object data; //返回具体数据
public static R ok(Object data){
R r = new R();
r.data = data;
return r;
}
public static R fail(Object data){
R r = new R();
r.code = 500; //错误码
r.flag = false; //错误状态
r.data = data;
return r;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
浏览器跨域问题及其前后端解决办法
跨域问题是浏览器的一种安全保护机制,类似于河南省串货到北京,不允许。
浏览器通过字符串比对:协议,主机地址,端口号 判断是否跨域
解决办法:
- 前端代理伪装地址
- 后端@CrossOrigin 允许访问
SpringMVC基于AOP的功能有哪些
- 日志记录
- 事务管理
- 安全控制
- 缓存管理
- 异常处理
- 性能监控
- 输入验证
- 审计跟踪
- 时间通知
SpringMVC声明式异常处理
配置方式:
通知注解 @ControllerAdvice @RestControllerAdvice
异常注解 @ExceptionHandler
Exception.class 兜底
SpringMVC拦截器 区别filter不能放行
配置方式:
-
实现HandlerIntercepter接口
-
配置bean :区别ref标签 和 bean标签
-
设置拦截地址
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/schedule/**"/>
<bean class="com.qxy.interceptors.InterceptorDemo"/>
</mvc:interceptor>
</mvc:interceptors>
- 设置优先级 先声明的优先级高 三个方法按照切面通知执行
因为interceptor被ArrayList数组装配,调用的时候preHandler是正序遍历拦截器数组,反之倒序。
Dispatcher 对于拦截器的调用时机如下:
//Dispatcher中对interceptor.preHandle方法的处理:
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//HandleExcutionChain中源码放置了这样一个拦截器数组,并且构造函数初始化
private final List<HandlerInterceptor> interceptorList;
// 配置拦截器的时候,先声明的先加入,对于pre采用正序遍历
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
if (!interceptor.preHandle(request, response, this.handler)) {
this.triggerAfterCompletion(request, response, (Exception)null);
return false;
}
}
//postHandle 完成拦截器则是倒序遍历
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
for(int i = this.interceptorList.size() - 1; i >= 0; --i) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
interceptor.postHandle(request, response, this.handler, mv);
}
}
//afterCompletion后置拦截器则是在后面,不管报不报异常都会执行,可以通过debug查看源码