SpringMVC知识点整合(下)

我的环境 idea 2019.1
jdk 1.8
Spring 5
Lombok插件 这里是使用和安装链接(包括idea和eclipse) @简单粗暴节省JavaBean代码插件 Lombok.jar
上一篇 @SpringMVC知识点整合(上) 基本环境搭建 环境搭建 pom.xml

UTF-8 1.8 1.8 5.0.2.RELEASE org.springframework spring-context ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-webmvc ${spring.version} javax.servlet servlet-api 2.5 provided javax.servlet.jsp jsp-api 2.0 provided org.projectlombok lombok 1.18.8 provided

配置web.xml 里面解决乱码和前端控制器
Archetype Created Web ApplicationDispatcherServlet org.springframework.web.servlet.DispatcherServlet contextConfigLocationclasspath:springmvc.xml 1DispatcherServlet / CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encodingUTF-8 CharacterEncodingFilter /*

新建 java root 和 resources root
编写 springmvc.xml

编写 index.jsp 和 /webapp/ipages/success.jsp
index.jsp
Title - 锐客网 helle

success.jsp
Title - 锐客网 success

然后部署到Tomcat

SpringMVC知识点整合(下)
文章图片
部署1
SpringMVC知识点整合(下)
文章图片
部署2
测试:

SpringMVC知识点整合(下)
文章图片
通过 5. 响应数据和结果视图 5.1.返回值分类 响应返回值是 String 类型 准备: response.jsp
response - 锐客网 返回字符串

方法 UserController.java
package cn.icanci.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @Author: icanci * @ProjectName: springmvc_day2 * @PackageName: cn.icanci.controller * @Date: Created in 2020/1/14 9:51 * @ClassAction: */ @Controller @RequestMapping("/user") public class UserController {@RequestMapping("/testString") public String testString() { System.out.println("UserController.testString"); return "success"; } }

测试:

SpringMVC知识点整合(下)
文章图片
测试通过
下面测试传递对象到jsp页面 其实这里和JavaWeb很像 只是有些地方框架为我们做了封装
执行的方法:UserController.java
package cn.icanci.controller; import cn.icanci.domain.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; /** * @Author: icanci * @ProjectName: springmvc_day2 * @PackageName: cn.icanci.controller * @Date: Created in 2020/1/14 9:51 * @ClassAction: */ @Controller @RequestMapping("/user") public class UserController {@RequestMapping("/testString") public String testString(Model model) { System.out.println("UserController.testString"); //模拟从数据库中查询一个 User 对象 User user = new User(); user.setUsername("haxi"); user.setPassword("445454"); user.setAge(16); model.addAttribute("user",user); return "success"; } }

success.jsp
Title - 锐客网 success ${user.username} ${user.password}

测试结果

SpringMVC知识点整合(下)
文章图片
页面的结果 响应返回值是 void 类型 准备方法:
@RequestMapping("/testVoid") public void testVoid(Model model) { System.out.println("UserController.testVoid"); }

准备界面 超链接
response - 锐客网 返回字符串
无返回值类型

跳转报错 报错信息说明 没有找到对应的jsp界面

SpringMVC知识点整合(下)
文章图片
报错信息
解决方法
1.在对应路径下建立 包和文件
2.使用HttpServletRequest对象 进行请求转发跳转到 WEB-INF 下的某个文件 或者 HtttpServletRequest 对象的重定向 跳转
3.直接输出一个界面
@RequestMapping("/testVoid") public void testVoid(HttpServletRequest req, HttpServletResponse resp) { System.out.println("UserController.testVoid"); try { //请求转发 //req.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(req, resp); //重定向 //resp.sendRedirect("/index.jsp"); //有的时候直接响应 //设置中文乱码 resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html; charset=utf-8"); resp.getWriter().println("hello"); } catch (Exception e) { e.printStackTrace(); } }

返回值类型是 ModelAndView ModelAndView 是 SpringMVC 为我们提供的一个对象,该对象也可以用作控制器方法的返回值。
该对象中有两个方法:
//把User对象存储到mv对象中去 也会把user对象存储到 request对象中去 mv.addObject("user",user); //跳转到那个界面 mv.setViewName("success");

@RequestMapping("/testModelAndView") public ModelAndView testModelAndView() { System.out.println("UserController.testModelAndView"); ModelAndView mv = new ModelAndView(); //模拟从数据库中查询一个 User 对象 User user = new User(); user.setUsername("haxi"); user.setPassword("445454"); user.setAge(16); //把User对象存储到mv对象中去 也会把user对象存储到 request对象中去 mv.addObject("user",user); //跳转到那个界面 mv.setViewName("success"); return mv; }

测试

SpringMVC知识点整合(下)
文章图片
测试通过 5.2 转发和重定向 实例代码
@RequestMapping("/testForwardOrRedirect") public String testForwardOrRedirect() { System.out.println("UserController.testForwardOrRedirect"); //return"forward:/WEB-INF/pages/success.jsp"; return"redirect:/index.jsp"; }

5.3 ResponseBody 响应 json 数据 作用:
该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的
数据如:json,xml 等,通过 Response 响应给客户端
准备界面
response - 锐客网 返回字符串
无返回值类型
ModelAndView
testForwardOrRedirect

配置springmvc.xml 因为 前端控制器拦截了资源 导致不能加载


使用响应json数据发送数据
前端界面 此界面用来测试是否可以响应 alert函数
response - 锐客网 返回字符串
无返回值类型
ModelAndView
testForwardOrRedirect

后端方法
@RequestMapping("/testAjax") public void testAjax(@RequestBody String body){ System.out.println("UserController.testAjax"); System.out.println(body); }

测试

SpringMVC知识点整合(下)
文章图片
接收到了数据
如果需要把json转换为JavaBean,还需要一个jar包
导入依赖
com.fasterxml.jackson.core jackson-databind 2.9.0 com.fasterxml.jackson.core jackson-core 2.9.0 com.fasterxml.jackson.core jackson-annotations 2.9.0

response.jsp
response - 锐客网 返回字符串
无返回值类型
ModelAndView
testForwardOrRedirect

方法
@RequestMapping("/testAjax") public @ResponseBody User testAjax(@RequestBody User user){ System.out.println("UserController.testAjax"); //客户端传输的是json 后台那数据封装到 JavaBean中 System.out.println(user); user.setUsername("hashTable"); System.out.println(user); return user; }

测试结果

SpringMVC知识点整合(下)
文章图片
接收的参数
SpringMVC知识点整合(下)
文章图片
控制台打印的对象数据 6.SpringMVC实现文件上传 JavaWeb中的表单上传文件的回顾 文件上传的必要前提
A form 表单的 enctype 取值必须是:multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型
B method 属性取值必须是 Post
C 提供一个文件选择域
文件上传的原理分析 当 form 表单的 enctype 取值不是默认值后,request.getParameter()将失效。
enctype=”application/x-www-form-urlencoded”时,form 表单的正文内容是:
key=value&key=value&key=value
当 form 表单的 enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成:
每一部分都是 MIME 类型描述的正文
-----------------------------7de1a433602ac 分界符
Content-Disposition: form-data; name="userName" 协议头
aaa 协议的正文
-----------------------------7de1a433602ac
Content-Disposition: form-data; name="file";
filename="C:\Users\zhy\Desktop\fileupload_demofile\b.txt"
Content-Type: text/plain 协议的类型(MIME 类型)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-----------------------------7de1a433602ac--
借助第三方组件 使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和commons-io。commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它工作时需要 commons-io 包的支持。
使用之前的基本环境 a.使用传统方式文件上传 准备一个类和方法 UserController .java
package cn.icanci.controller; import cn.icanci.domain.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.jws.WebParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Author: icanci * @ProjectName: springmvc_day2 * @PackageName: cn.icanci.controller * @Date: Created in 2020/1/14 9:51 * @ClassAction: */ @Controller @RequestMapping("/user") public class UserController { /** * 第一个文件上传的方法 * * @return */ @RequestMapping("/testFileUpload1") public String testFileUpload1() { System.out.println("UserController.testFileUpload1"); return "success"; } }

index.jsp
Title - 锐客网 hello 文件上传
选择文件:

导入依赖
commons-fileupload commons-fileupload 1.3.1 commons-io commons-io 2.4

上传文件的控制类 testFileUpload1.java
package cn.icanci.controller; import java.util.UUID; import java.io.File; import java.util.List; import cn.icanci.domain.User; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.jws.WebParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Author: icanci * @ProjectName: springmvc_day2 * @PackageName: cn.icanci.controller * @Date: Created in 2020/1/14 9:51 * @ClassAction: */ @Controller @RequestMapping("/user") public class UserController { /** * 第一个文件上传的方法 传统方式 * * @return */ @RequestMapping("/testFileUpload1") public String testFileUpload1(HttpServletRequest req) { System.out.println("UserController.testFileUpload1"); //使用 fileupload 组件完成文件上传 //上传的位置 String path = req.getSession().getServletContext().getRealPath("/uploads/"); //判断路径是否存在 System.out.println(path); File file = new File(path); if (!file.exists()) { file.mkdir(); }//解析req对象 获取上传文件的 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); //解析 req try { List fileItems = upload.parseRequest(req); //遍历 for (FileItem item : fileItems) { //判断上传的文件是不是上传文件项 if (item.isFormField()) { //说明是普通表单项 System.out.println("item form"); } else { System.out.println("upload"); //说明是文件表单项 //获取上产文件的名称 String fileName = item.getName(); //完成文件上传 try { UUID uuid = UUID.randomUUID(); item.write(new File(path, uuid.toString().replace("-", "") + "_" + fileName)); //删除临时文件 item.delete(); } catch (Exception e) { e.printStackTrace(); } } } } catch (FileUploadException e) { e.printStackTrace(); } System.out.println("上传成功"); return "success"; } }

测试
控制台打印一些信息

SpringMVC知识点整合(下)
文章图片
控制台打印的信息
文件路径

SpringMVC知识点整合(下)
文章图片
上传到服务器路径下文件夹里面
第一种方式测试通过 b.使用SpringMVC传统的方式上传文件 SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的name属性名称相同。
配置springmvc.xml中的文件解析器

注意:
  1. 此处 id的值必须为 multipartResolver 否则报错以下异常

    SpringMVC知识点整合(下)
    文章图片
    id的值必须为 multipartResolver 否则报错此异常
  2. 如果文件大小超出设置的 就会报以下异常

    SpringMVC知识点整合(下)
    文章图片
    如果文件大小超出设置的 就会报以下异常
    修改之后 此时测试通过

    SpringMVC知识点整合(下)
    文章图片
    通过
c.使用SpringMVC跨服务器方式的文件上传 在实际开发中,我们会有很多处理不同功能的服务器。例如:
应用服务器:负责部署我们的应用
数据库服务器:运行我们的数据库
缓存和消息服务器:负责处理大并发访问的缓存和消息
文件服务器:负责存储用户上传文件的服务器。
首先需要搭建环境 配置一个新的服务器 注意端口需要修改 同时 Tomcat 的 conf 目录下的 server.xml 的宽口也要修改
选中刚刚的项目 右键 new 一个模块 按照初始配置就可以 或者直接复制之前的项目 代码 然后测试

SpringMVC知识点整合(下)
文章图片
new 一个模块
测试结果
index.jsp
Title - 锐客网 嘻嘻嘻

SpringMVC知识点整合(下)
文章图片
通过 到之前的pom.xml里面导入坐标
com.sun.jersey jersey-core 1.18.1 com.sun.jersey jersey-client 1.18.1

index.jsp
Title - 锐客网 hello 文件上传传统方式
选择文件:

SpringMVC方式
选择文件:

SpringMVC开服务器方式
选择文件:

后台代码
package cn.icanci.controller; import java.io.IOException; import java.util.UUID; import java.io.File; import java.util.List; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; /** * @Author: icanci * @ProjectName: springmvc_day2 * @PackageName: cn.icanci.controller * @Date: Created in 2020/1/14 9:51 * @ClassAction: */ @Controller @RequestMapping("/user") public class UserController {/** * @param upload 此处的名字和你表单中的名字 必须一样 * @return */ @RequestMapping("/testFileUpload3") public String testFileUpload3(MultipartFile upload) { System.out.println("UserController.testFileUpload3"); //定义上传服务器的地址 String path = "http://localhost:8080/f2/uploads/"; //说明是文件表单项 //获取上产文件的名称 String fileName = upload.getOriginalFilename(); //完成文件上传 UUID uuid = UUID.randomUUID(); fileName = uuid.toString().replace("-", "") + "_" + fileName; System.out.println(fileName); //跨服务器上传 //创建客户端的对象 Client client =Client.create(); //和图片服务器进行链接 WebResource wr = client.resource(path+fileName); //上传文件 try { wr.put(upload.getBytes()); } catch (IOException e) { e.printStackTrace(); } return "success"; }/** * @param req * @param upload 此处的名字和你表单中的名字 必须一样 * @return */ @RequestMapping("/testFileUpload2") public String testFileUpload2(HttpServletRequest req, MultipartFile upload) { System.out.println("UserController.testFileUpload2"); //使用 fileupload 组件完成文件上传 //上传的位置 String path = req.getSession().getServletContext().getRealPath("/uploads/"); //判断路径是否存在 System.out.println(path); File file = new File(path); if (!file.exists()) { file.mkdir(); } //说明是文件表单项 //获取上产文件的名称 String fileName = upload.getOriginalFilename(); //完成文件上传 UUID uuid = UUID.randomUUID(); fileName = uuid.toString().replace("-", "") + "_" + fileName; System.out.println(fileName); //完成文件上传 try { upload.transferTo(new File(path,fileName)); } catch (IOException e) { e.printStackTrace(); } return "success"; }/** * 第一个文件上传的方法 传统方式 * * @return */ @RequestMapping("/testFileUpload1") public String testFileUpload1(HttpServletRequest req) { System.out.println("UserController.testFileUpload1"); //使用 fileupload 组件完成文件上传 //上传的位置 String path = req.getSession().getServletContext().getRealPath("/uploads/"); //判断路径是否存在 System.out.println(path); File file = new File(path); if (!file.exists()) { file.mkdir(); }//解析req对象 获取上传文件的 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); //解析 req try { List fileItems = upload.parseRequest(req); //遍历 for (FileItem item : fileItems) { //判断上传的文件是不是上传文件项 if (item.isFormField()) { //说明是普通表单项 System.out.println("item form"); } else { System.out.println("upload"); //说明是文件表单项 //获取上产文件的名称 String fileName = item.getName(); //完成文件上传 try { UUID uuid = UUID.randomUUID(); item.write(new File(path, uuid.toString().replace("-", "") + "_" + fileName)); //删除临时文件 item.delete(); } catch (Exception e) { e.printStackTrace(); } } } } catch (FileUploadException e) { e.printStackTrace(); } System.out.println("上传成功"); return "success"; } }

开启两个服务器 然后测试
执行之后报错
如图 是因为没有这个文件夹

SpringMVC知识点整合(下)
文章图片
报错信息
创建此文件夹

SpringMVC知识点整合(下)
文章图片
创建此文件夹 7.SpringMVC的异常处理 环境搭建和开始的时候一样 步骤
  1. 自定义异常类
  2. 自定义异常处理器
  3. 配置异常处理器
准备 自定义异常类 SelfException.java
package cn.icanci.exception; import lombok.Data; import java.security.spec.ECFieldF2m; /** * @Author: icanci * @ProjectName: springMVCException * @PackageName: cn.icanci.exception * @Date: Created in 2020/1/14 22:54 * @ClassAction: 自定义异常类 */ @Data public class SelfException extends Exception { //用来存储异常信息的 private String message; public SelfException(){} public SelfException(String message){ this.message = message; } public void setMessage(String message){ this.message = message; } }

UserController.java
package cn.icanci.controller; import cn.icanci.exception.SelfException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @Author: icanci * @ProjectName: springMVCException * @PackageName: cn.icanci.controller * @Date: Created in 2020/1/14 22:46 * @ClassAction: */ @Controller @RequestMapping("/user") public class UserController {@RequestMapping("/testException") public String testException() throws Exception{System.out.println("UserController.testException"); try { int a = 10/0; } catch (Exception e) {e.printStackTrace(); throw new SelfException("用户有异常"); }return "success"; } }

SelfExceptionResolver.java 处理异常到界面
package cn.icanci.exception; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Author: icanci * @ProjectName: springMVCException * @PackageName: cn.icanci.exception * @Date: Created in 2020/1/14 23:05 * @ClassAction: */ public class SelfExceptionResolver implements HandlerExceptionResolver { /** * 处理业务逻辑 * @param httpServletRequest * @param httpServletResponse * @param o * @param e * @return */ public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { //准备获取异常对象 SelfException exception = null; if(e instanceof SelfException){ exception = (SelfException) e; }else { e = new SelfException("系统正在维护.//.///"); } //创建 ModelAndView 对象 ModelAndView mv = new ModelAndView(); mv.addObject("errorMsg",e.getMessage()); mv.setViewName("error"); return mv; } }

准备 error.jsp界面
Title - 锐客网 ${errorMsg}

在springmvc,xml 配置异常处理器

测试

SpringMVC知识点整合(下)
文章图片
测试 8.SpringMVC中的拦截器 基本环境和之前的一样
  1. SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链
    中的拦截器会按着定义的顺序执行。
  3. 拦截器和过滤器的功能比较类似,有区别
  4. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
  5. 拦截器是SpringMVC框架独有的。
  6. 过滤器配置了/*,可以拦截任何资源。
  7. 拦截器只会对控制器中的方法进行拦截。
  8. 拦截器也是AOP思想的一种实现方式
  9. 想要自定义拦截器,需要实现HandlerInterceptor接口。
自定义拦截器
  1. 创建类,实现HandlerInterceptor接口,重写需要的方法
  2. 在springmvc.xml中配置拦截器类
HandlerInterceptor接口中的方法
1. preHandle方法是controller方法执行前拦截的方法 1. 可以使用request或者response跳转到指定的页面 2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。 3. return false不放行,不会执行controller中的方法。 2. postHandle是controller方法执行后执行的方法,在JSP视图执行前。 1. 可以使用request或者response跳转到指定的页面 2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。 3. postHandle方法是在JSP执行后执行 1. request或者response不能再跳转页面了

后台代码
/** * 自定义拦截器 */ public class MyInterceptor2 implements HandlerInterceptor{/** * 预处理,controller方法执行前 * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法 * return false不放行 * @param request * @param response * @param handler * @return * @throws Exception */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor1执行了...前2222"); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response); return true; }/** * 后处理方法,controller方法执行后,success.jsp执行之前 * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor1执行了...后2222"); // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response); }/** * success.jsp页面执行后,该方法会执行 * @param request * @param response * @param handler * @param ex * @throws Exception */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor1执行了...最后2222"); }}

SpringMVC的知识点总结告一段落 之后有补充的会添加进来 【SpringMVC知识点整合(下)】此处 @我自己 这是QQ聊天的链接 欢迎一起吹

    推荐阅读