**SpringMVC 笔记2 [共2篇]*

一. 响应

1.1 概述:就是把后台的数据返回给浏览器/用户;

1.2 搭建环境:

  1. 创建项目:Maven->选择骨架或者手动添加… 在main中创建java,resources,webapp三个包,webapp包下创建WEB-INF,pages:创建succes.jsp;[成功的返回页面]
  2. 导入相关坐标… [可以应用版本锁定]
  3. 引入前端控制器[固定写法]
  4. springmvc.xml:开启注解扫描,视图解析器,注解支持
  5. 删除webapp中的index.jsp重新创建一个;

1.3. 响应数据和结果视图:

  1. Controller方法返回字符串 【使用Model存入数据再返回】
    1. 解析: Controller方法执行后,返回的字符串根据视图解析器所前后拼接的文件名和地址,就能成功的跳转到所需的页面;
    2. jsp页面接收对象:
      • 在Controller方法中,使用model.addAttribute(“user”,user) [该方法需传入一个Model]
      • Model不需要我们创建,这是框架为我们生成的;
      • isELIgnored=“false” [识别el表达式]
      • 使用${user.username}进行取值…
      • 示例:
			* @Controller
			* @RequestMapping("/user")
			* public class UserController {
			* /**
			* *请求参数的绑定
			* */
			* @RequestMapping(value="/initUpdate")
			* public String initUpdate(Model model) {
			* // 模拟从数据库中查询的数据
			* User user = new User();
			* user.setUsername("张三");
			* user.setPassword("123");
			* user.setMoney(100d);
			* user.setBirthday(new Date());
			* model.addAttribute("user", user);
			* return "update";
			* }
			* }
  1. Controller方法返回void 【return;】

    1. 请求转发:请求转发是一次请求,不能简写 [手动跳动转发,不会触动视图解析器,需要自己写全路径和文件格式]
      示例:request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
    2. 重定向:请求转发是可以直接访问web-inf下的文件,所以不用写虚拟地址;
      reponse.sendRedirect(request.getContextPath()+"WEB-INF/pages/xxx.jsp")
    3. 解决中文乱码:
      reponse.setCharacterEncoding("UTF-8");
      response.setContentType("text/html;charset=UTF-8");
    4. 直接响应:
      response.getWriter().print("你好");
    5. 注意:程序运行到响应,那么响应后面的代码应写上return;
      • 一次请求对应一次响应,所以response.getWriter.print(“xxx”),里面打印的需要在整个方法执行完才会整体的去响应,在此之前它是将打印的语句储备起来,还未发送响应;所以使用return;进行结尾,那么就可以不让框架继续执行其他,直接返回;
    6. 使用框架后,request,response这些以后都不经常用了;
    7. 为什么domain实体类要实现Serializable接口?
      • 它是实体类,专门用来存储类,它存在于内存中,实现序列化接口,可以将封装好的类保存到硬盘中,如果突然断电关机什么意外情况,可以反序列化还原;
      • 实现该接口,才可以将该对象远程调用,远程传输到其他的服务器,传输时以流的形式
    8. 实体类中的常见问题:
      1. 如果实体类中写了有参构造,那么需要再为它创建一个无参构造;
      2. 成员变量最好使用private修饰,加强安全性,只能通过get,set对其操作;
      3. 成员变量尽量使用包装类型,不要使用基本类型,即尽量使用Integer类,而不使用int基本类型;
      4. Integer修饰的变量可以为空,但基本类型不能为null; 比如:private Integer ge=null;
  2. ModelAndView:

    1. 把user对象储存到mv对象中,也会把user对象存入到request对象;
    2. 它既可以储存键值对[发挥model],它也可以转发视图[view]的作用;
      • 示例:
    		* @RequestMapping("/testModelAndView")
    		* public ModelAndView testModelAndView(){
    		* ModelAndView mv =new ModelAndView();
    		* System.out.println("testModelAndView方法执行了...")
    		* User user=new User();
    		* user.setUsername("小枫")
    		* user.setPassword(123);
    		* user.setAge(30);
    		* mv.addObject("user",user);
    		* mv.setViewName("success");
    		* reutrn mv;
    		* }
    
    1. 使用关键字的方式进行转发或者重定向 [使用关键字是不会被视图解析器所管理,需要自己手动补全路径
    	 @RequestMapping("/testForwardOrRedirect")
    	 public String testForwardOrRedirect(){
    	 //请求的转发:
    	 return "forward:/WEB-INF/pages/success.jsp";
    	 //重定向
    	 return "redirect:/index.jsp";
    	 }
    
  3. ResponseBody响应json数据

    1. DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置:
      • //前端控制前,哪些资源不拦截:
      <mvc:resources location="/css/" mapping="/css/**"/>
      <mvc:resources location="/images/" mapping="/images/**"/>
      <mvc:resources location="/js/" mapping="/js/**"/>
      
    2. 特点:
      1. mvc:resources标签配置不过滤
      2. location元素表示webapp目录下的包下的所有文件
      3. mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b
  4. 模拟示例:

    1. 模拟异步请求响应:
      1. 服务器:
      	 @RequestMapping("/testAjax")
      	 public void testAjax(@RequestBody String body){
      	 //
      	 System.out.println(body);
      	 }
      
      1. 浏览器:
      	 $(function(){
      	 $("#btn").click(funcation(){
      	 $.ajax({
      	 url:""user/testAjax",
      	 contextType:"application/json;charset=UTF-8",				//设置了这种格式,提交是以json格式提交,如果不以此设置,$.get |$.post 则都是表单提交格式
      	 data:'{"username":"heihei","password":"123","age":30}',
      	 dataType:"json",
      	 type:"post",
      	 success:function(date){
      	 //data服务器端响应的json数据,进行解析。
      	 }
      	 })
      	 })
      
      1. 如果传入已经定义好了的domain里User实体类,那么也可以直接传入这个实体类,只要属性值对应的上,那么springmvc就会自动绑定,与ajax发送的属性值一一对应;

二. 文件上传

2.1 文件上传概述

  1. 文件上传三要素: [只要是文件上传,就必须满足这三个要素]
    1. form表单的enctype取值必须是:multipart/form-data
      默认值是:application/x-222-form-urlencoded
      enctype:是表单请求正文的类型
    2. method属性必须是post
      • get请求会把文件携带在地址栏上,而get请求是有大小限制的;
    3. 提供一个文件选择域而且必须有name属性:
      <input type="file">
  2. 借助第三方组件实现文件上传:
    导入commons-fileupload-1.3.1.jar和commons-io-2.4.jar
  3. 案例实现:

2.2 文件上传实战案例

  1. 搭建开发环境:
    1. 创建一个新的maven项目: 坐标,springmvc.xml,web.xml
			<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
			</dependency>
			<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
			</dependency>
  1. 补全包路径
  2. 编写文件上传的JSP页面:
		<h3>文件上传</h3>
		<form action="user/fileupload" method="post" enctype="multipart/form-data">
		选择文件:<input type="file" name="upload"/><br/>
		<input type="submit" value="上传文件"/>
		</form>
  1. 编写文件上传的Controller控制器:
			@RequestMapping(value="/fileupload")
			public String fileupload(HttpServletRequest request) throws Exception {
			// 先获取到要上传的文件目录
			String path = request.getSession().getServletContext().getRealPath("/uploads");
			// 创建File对象,一会向该路径下上传文件
			File file = new File(path);
			// 判断路径是否存在,如果不存在,创建该路径
			if(!file.exists()) {
			file.mkdirs();
			}
			// 创建磁盘文件项工厂
			DiskFileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload fileUpload = new ServletFileUpload(factory);
			// 解析request对象
			List<FileItem> list = fileUpload.parseRequest(request);
			// 遍历
			for (FileItem fileItem : list) {
			// 判断文件项是普通字段,还是上传的文件
			if(fileItem.isFormField()) {
			}else {
			// 上传文件项
			// 获取到上传文件的名称
			String filename = fileItem.getName();
			// 上传文件
			fileItem.write(new File(file, filename));
			// 删除临时文件
			fileItem.delete();
			}
			}
			return "success";
			}
  1. SpringMVC实现原理分析:

    1. 选择文件后点击上传;
    2. 当文件上传后,通过request进入到前端控制器
    3. 前端控制器通过添加的配置文件解析器,解析request并返回upload
    4. 前端控制器调用Controller,将upload传入Controller类下的fileuoload2(MultipartFile upload),然后对其进行操作;
    5. 注意:前端的name属性值必须和后端Controller类下finduoload2内传入的参数名保持一致;
  2. 实现代码:

    1. SpringMVC传统方式文件上传:

      1. SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名必须和表单file标签的name属性相同;
      2. 代码如下:
        			@RequestMapping(value="/fileupload2")
        			public String fileupload2(HttpServletRequest request,MultipartFile upload) throws
        			Exception {
        			System.out.println("SpringMVC方式的文件上传...");
        			// 先获取到要上传的文件目录
        			String path = request.getSession().getServletContext().getRealPath("/uploads");
        			// 创建File对象,一会向该路径下上传文件
        			File file = new File(path);
        			// 判断路径是否存在,如果不存在,创建该路径
        			if(!file.exists()) {
        			file.mkdirs();
        			}
        			// 获取到上传文件的名称
        			String filename = upload.getOriginalFilename();
        			String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        			// 把文件的名称唯一化
        			filename = uuid+"_"+filename;
        			// 上传文件
        			upload.transferTo(new File(file,filename));
        			return "success";
        			}
        
      3. 配置文件解析器对象: 【如果是传统的文件上传那么会报错,只有SpringMVC的文件上传才能起作用】
      	<!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
      	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      	<property name="maxUploadSize" value="10485760"/>             // 10485760=1024*1024*10=10MB
      	</bean>
      
    2. SpringMVC跨服务器文件上传:

      1. 搭建图片服务器:
        1. 根据文档配置tomcat9的服务器,现在是两个服务器
        2. 导入资料中day02_SpringMVC5_02image项目,作为图片服务器使用 [两个tomcat模拟两台服务器,一台服务器作为控制器接收请求,一台服务器作为图片储存]
      2. 实现SpringMVC跨服务器文件上传
  3. 导入开发需要的jar包:

    1.     <dependency>
      	<groupId>com.sun.jersey</groupId>
      	<artifactId>jersey-core</artifactId>
      	<version>1.18.1</version>
      	</dependency>
      	<dependency>
      	<groupId>com.sun.jersey</groupId>
      	<artifactId>jersey-client</artifactId>
      	<version>1.18.1</version>
      	</dependency>
      
    2. 编写文件上传JSP页面:
      		<h3>跨服务器的文件上传</h3>
      		<form action="user/fileupload3" method="post" enctype="multipart/form-data">
      		选择文件:<input type="file" name="upload"/><br/>
      		<input type="submit" value="上传文件"/>
      		</form>
      
    3. 编写控制器:
      	@RequestMapping(value="/fileupload3")
      	public String fileupload3(MultipartFile upload) throws Exception {
      	System.out.println("SpringMVC跨服务器方式的文件上传...");
      	// 定义图片服务器的请求路径
      	String path = "http://localhost:9090/day02_springmvc5_02image/uploads/";
      	// 获取到上传文件的名称
      	String filename = upload.getOriginalFilename();
      	String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
      	// 把文件的名称唯一化
      	filename = uuid+"_"+filename;
      	// 向图片服务器上传文件
      	// 创建客户端对象
      	Client client = Client.create();
      	// 连接图片服务器
      	WebResource webResource = client.resource(path+filename);
      	// 上传文件
      	webResource.put(upload.getBytes());
      	return "success";
      	}
      
    		
    
    

三. 异常处理

3.1 SpringMVC异常处理流程:

  1. 浏览器-> 前端控制器-> web-> service-> dao
  2. 如果出现错误,默认处理方案是将错误依次往上抛出:
    • 假如dao层出现错误,会抛给service->web->前端控制器->浏览器
  3. 出现错误如果将错误出现在浏览器上,会降低用户体验,产生不好的影响;
    • 此时可在前端控制器添加一个异常处理器组件,它将从内部抛给前端控制器的异常拦截,并将异常进行处理,返回给浏览器一个友好的错误提示页面;
  4. Controller调用service,service调用dao,异常都是向上抛出的,最终有DispathcherServlet找异常处理器进行异常的处理。
  5. 示例见下方:

3.2 自定义异常类:

		package cn.itcast.exception;
		public class SysException extends Exception{
		private static final long serialVersionUID = 4055945147128016300L;
		// 异常提示信息
		private String message;
		public String getMessage() {
		return message;
		}
		public void setMessage(String message) {
		this.message = message;
		}
		public SysException(String message) {
		this.message = message;
		}}

3.3 自定义异常处理器

			package cn.itcast.exception;
			import javax.servlet.http.HttpServletRequest;
			import javax.servlet.http.HttpServletResponse;
			import org.springframework.web.servlet.HandlerExceptionResolver;
			import org.springframework.web.servlet.ModelAndView;
			/**
			* 异常处理器
			* @author rt
			*/
			public class SysExceptionResolver implements HandlerExceptionResolver{
			/**
			* 跳转到具体的错误页面的方法
			*/
			public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse
			response, Object handler,
			Exception ex) {
			ex.printStackTrace();
			SysException e = null;
			// 获取到异常对象
			if(ex instanceof SysException) {
			e = (SysException) ex;
			}else {
			e = new SysException("请联系管理员");
			}
			ModelAndView mv = new ModelAndView();
			// 存入错误的提示信息
			mv.addObject("message", e.getMessage());
			// 跳转的Jsp页面
			mv.setViewName("error");
			return mv;
			}
			}

3.4 配置异常处理器:

			< bean id="sysExceptionResolver" class="cn.itcast.exception.SysExceptionResolvaer"/>

四. 拦截器

  1. SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理;
  2. 拦截器链:(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
  3. 解释:
    • 过滤器:是servlet规范中的一部分,任何java web工程都可以使用。
    • 拦截器:是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能用。
    • 过滤器:是在url-pattern中配置了/*之后,可以对所有要访问的资源拦截;
    • 拦截器:它是只会拦截访问的控制器方法,如果访问的是jsp,html,css,image或者js是不会进行拦截的。
    • 它也是AOP思想的具体应用。
    • 我们要想自定义拦截器,要求必须实现:HandlerInterceptor接口。
  4. 不同点:过滤器什么都拦截,而拦截器只能拦截特定的;即过滤器的范围大于拦截器;

博主还有更多有用的文章哦,有时间的话就点进去翻翻吧,一起进步~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗余

码字来之不易,您的鼓励我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值