目录
1、MVC架构:
2 、请求&响应【重点】
3 、参数绑定 【重点】
4、路径@PathVariable
5 、页面跳转[熟悉]
6、 会话[重点]
7、拦截器【开发必用】
8、 json处理【重点】
9、 文件上传
10、异常处理
引言:
根据不同的事情由不同的类去处理,内部单一职责
Model: 模型类,例如封装数据的实体类(entity, model, pojo),业务模型(Service),数据层(Dao)
View: 视图,展示数据的.HTML,JSP
Controller: 控制器,控制整个流程走向. 决定是否能接收请求,调用哪个业务,跳转哪个页面,Servlet
MVC框架特点
封装了Servlet
接收请求方便(一个类中,不同的方法就可以接收不同的请求)
接收请求数据方便(自动封装)
响应数据方便(自动响应json)
其实我们之前的那些案例中就已经使用了请求和响应
@GetMapping("/ioc")、@PostMapping("/ioc")等就是绑定映射路径和处理请求的方法的,返回值就是响应(跳转页面)
前端-》controller 参数的绑定 和请求相关!!!
所谓参数绑定,就是前端发请求中的数据,可以直接在Controller的方法参数中接收.即前端请求数据和后端方法参数绑定.
List和Map集合要用@RequestParam
前端
路径参数绑定
路径参数101
后端
@GetMapping("/user/{id}") public String path(@PathVariable int id){ System.out.println("id = " + id); // id=101 return "ok.html"; }
ps: 能接收到请求中的id为101,但是响应回报错.因为使用
现在前后端分离的项目 不用!!!跳转都在前端!!!
回顾之前学过的servlet中跳转页面的功能
请求转发:forward
req.getDispatcherServlet().forward(req,resp)
请求路径不变
是服务器内部请求
一次请求
请求域的数据可以共享
重定向:redirect
resp.sendRedirect();
请求路径改变
是浏览器行为
两次请求
请求域的不能共享
请求转发
注意: 现在我们一直都在使用请求转发,因为默认就是请求转发跳转页面
也可以手动显示的在Controller的方法的返回值中写forward:路径即可完成跳转
例如: forward:/ok.html forward:/test
注意: 跳转后的路径要写完整
重定向
在Controller的方法的返回值中写redirect:路径即可完成跳转
例如: redirect:/ok.html redirect:/test
注意: 跳转后的路径要写完整
如果需要在控制层中使用session存储会话数据,比如登录的用户信息,就可以直接在方法的参数列表中定义HttpSession对象即可
/**
* 演示session会话
* @param session
* @return
*/
@GetMapping("/sess")
public String sess (HttpSession session) {
session.setAttribute("username", "狗蛋");
return "ok.html";//forward 转发
}
@GetMapping("/getsess")
public String getSess (HttpSession session) {
System.out.println(session.getAttribute("username"));
return "ok.html";//forward 转发
}
使用步骤,与Servlet中的过滤器思路基本一致
编写自定义拦截器类
实现接口HandlerInterceptor
重写拦截方法
配置拦截器
这个不一样,以前是配置在web.xml中或者加上注解@WebFilter
现在SpringBoot推荐使用java类的方式配置
07 Springboot(new) · 语雀
见文档!!!
自定义拦截器类
@Component public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("my preHandle"); // false 所有都拦截,排除在外的不拦截 return false; } }
拦截器配置类
@Configuration // !!!加注解!!!!配置类 public class MyConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // addPathPatterns 定义拦截的路径 // excludePathPatterns 定义放行的路径 // 这两个方法支持不定长参数,可以设置多个拦截/放行路径 registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/test"); } }
后续工作项目,都是前后端分离开发,前后端使用JSON数据交互
前端发送json,使用axios技术(类似于ajax),vue中就使用axios发送请求
后端接收json,然后响应给前端json
总结: 前端发送请求给后端(controller) 返回JSON数据给前端
前端咋接到这个json数据? 用ajax技术!!!
现在没有讲ajax,所以现在讲课 只需要学习后端返回json数据即可
前端发送json等vue时候再演示
现在演示响应JSON数据,非常简单,方法加上@ResponseBody即可,就会将任何解析为json返回
public class R {
private String code;
private String msg;
private Object data;
public static R ok () {
return new R("200", "成功");
}
//有可能公司状态码不是200
public static R ok (String code) {
return new R(code, "成功");
}
public static R ok (String code,String msg) {
return new R(code, msg);
}
public static R ok (String code,String msg, Object data) {
return new R(code, msg, data);
}
public static R fail () {
return new R("500", "失败");
}
public static R fail (String code, String msg) {
return new R(code, msg);
}
public R() {
}
public R(String code, String msg) {
this.code = code;
this.msg = msg;
}
public R(String code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
图片上传
上传tomcat服务器/上传本地磁盘/专业的文件存储服务器(阿里OSS,腾讯OSS,七牛云存储)
前端
文件上传
后端: 上传到tomcat服务器上
commons-fileupload commons-fileupload 1.3.2 commons-io commons-io 2.4
/**
* 接收文件,上传文件到服务器
* ----------------------
* 方法的参数列表设置MultipartFile类型参数,
* 参数名与前端name一致,即可封装
*/
@PostMapping("/upload")
public R upload(MultipartFile img, HttpServletRequest request) throws IOException {
/**
* img中有前端发的那个文件对象全部信息
* 思路:
* 获得原始文件名
* 重命名文件名
* 确定Tomcat位置,创建文件夹单独存储图片
* 开始上传
*/
// 1.获得上传的对象 参数img就是文件对象
// 2. 获得最终上传的目的地路径(上传至服务器中当前项目下)
// 通过servlet方法获得路径,即最终上传到Tomcat的/upload
String realPath = request.getServletContext().getRealPath("/upload");
System.out.println("服务器中存储图片的真实路径: "+realPath);
// 2.1 将最终目的文件夹创建出来
File file = new File(realPath);
// 判断该文件是否存在
if(!file.exists()) {
// 不存在则创建出
file.mkdir();
}
// 2.2 获得文件名
/*
* 文件名重复时不能重复上传文件
*/
String fileName = img.getOriginalFilename();
System.out.println("原始文件名:" + fileName);//"xixi.goudna.png"
/*
* 根据.拆分字符串,获得文件后缀名
*/
String[] split = fileName.split("\\.");//
System.out.println("拆分后的文件信息:" + Arrays.toString(split));
String suffix = split[split.length - 1];
// 以当前毫秒值为文件名
long prefix = System.currentTimeMillis();
// 组装文件名
String newFileName = prefix+"."+suffix;//289292929.png
System.out.println("新的文件名 : "+newFileName);
// 2.3 确定上传路径
// // xxx/tomcat/upload/234234324.jpg
File newFile = new File(file,newFileName);
// 3. 用工具上传
FileUtils.writeByteArrayToFile(newFile, img.getBytes());
// 4 返回路径,测试使用,放查看是否上传成功
String path = "http://localhost:8080/upload/"+newFileName;
System.out.println(path);
/**
* 后续写项目时,还有第5步,即将图片路径存储到数据库
* 将来查询时查出,前端根据路径展现图片
*/
return R.ok(path);
}
因为是上传到服务的,上传后可以通过网络访问到图片
SpringBoot中有一个ControllerAdvice的注解,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用ExceptionHandler注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。
@RestControllerAdvice
public class MyGlobalExceptionHandler {
//@ExceptionHandler(value = {ArithmeticException.class, IndexOutOfBoundsException.class})
@ExceptionHandler(Exception.class)
//@ResponseBody
public R handlerException (Exception e){
System.out.println("全局异常处理器");
return R.fail("500", e.getMessage());
}
}