SpringMVC_03_控制器返回值类型、转发和重定向关键字、响应JSON数据、文件上传

第五章

5.1控制器的返回值类型

1、String类型

  • 返回的字符串,会根据配置好的视图解析器的路径,寻找对应的跳转

  • 案例:

    • 需求,查询“张三” 的信息,在成功界面输出

    • //主界面jsp文件:
      <a href="user/textReturnString" >查询张三的信息</a>
      ----------------------------------------------------------------------------
      //控制器:
      @Controller
      @RequestMapping("/user")
      public class UserController {
      	@RequestMapping("/textReturnString")
      	public String textReturnString(Model model){
      		//模拟在数据库中查询信息
      		User user = new User();
      		user.setName("张三");
      		user.setPassword("123456");
      		user.setAge(20);
      
      		//把对象存放到域中,方便在前端jsp页面的使用
      		model.addAttribute(user);
      		//会跳转到成功界面
      		return "success";
      	}
      }
      ---------------------------------------------------------------------------------
      //成功界面
      //在jsp页面,想使用EL表达式,取域中的值,先开启jsp页面支持el表达式(isELIgnored="false")
       <h3>恭喜你访问成功</h3>
        ${user.toString()}
      
      

2、void类型

  • 没有返回值,默认去找与控制器相同路径的一个页面,没有该资源,会报404错误

  • 怎么解决没有返回值的时候,会报错的问题??

    • 方法一:转发的方式指定页面
      • 想使用转发,先在控制器的参数中声明一下HttpServletRequest和HttpServletResponse的对象
      • request.getRequestDispatcher("/WEB-INF/pages/add.jsp").forward(request,response);
    • 方法二:重定向的方式指定页面
      • 想使用重定向,先在控制器的参数中声明一下HttpServletRequest和HttpServletResponse的对象
      • response.sendRedirect(request.getContextPath()+"/add2.jsp");
        • 转发是一层请求,不用再编写项目名称;而重定向是两次请求,需要写项目的名称
        • 利用request.getContextPath()方法得到项目的名称
    • 方法三:直接响应
      • 在控制器上通过输出流的方式,写出jsp的页面代码
    • 注意:以上三种方法,不会调用视图解析器
  • 案例源码:

    • <a href="user/textReturnVoid1" >void方式转发方式解决</a><br>
      <a href="user/textReturnVoid2" >void方式重定向方式解决</a><br>
      <a href="user/textReturnVoid3" >void方式直接响应方式解决</a><br>
      -------------------------------------------------------------------------------
      //转发
      @RequestMapping("/textReturnVoid1")
      public void textReturnVoid1(HttpServletRequest request, HttpServletResponse response) throws Exception {
      		System.out.println("转发页面执行了");
      		request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
      	}
      
      //重定向
      @RequestMapping("/textReturnVoid2")
      public void textReturnVoid2(HttpServletRequest request, HttpServletResponse response) throws Exception {
      		System.out.println("重定向页面执行了");
      		response.sendRedirect(request.getContextPath()+"/WEB-INF/pages/success.jsp");
      	}
      	
      //直接响应
      @RequestMapping("/textReturnVoid3")
       public void textReturnVoid3(HttpServletRequest request, HttpServletResponse response) throws Exception {
                  System.out.println("直接响应页面执行了");
                  //设置中文乱码
                  response.setCharacterEncoding("UTF-8");
                  response.setContentType("text/html;charset=UTF-8");
                  response.getWriter().write("恭喜你访问成功");
              }
      

3、ModelAndView类型

  • ModelAndView 是 SpringMVC 为我们提供的一个对象,该对象也可以用作控制器方法的返回值

    • ModelAndView对象相当于两个对象:
      • Model对象:该对象和在控制器方法形参中的是一样的(可以往域中存放内容(addObject方法)等的)
      • View对象:视图对象,调用setView()方法,可以设置为哪一个视图
    • 当ModelAndView对象做为控制器的返回值的时候,会自动的根据配置的视图解析器,寻找设置的那个视图的位置
  • 案例:

    • <a href="user/textReturnModelAndView">查询张三的信息</a>
      ---------------------------------------------------------------------------
      //返回值为ModelAndView
      @RequestMapping("/textReturnModelAndView")
      public ModelAndView textReturnModelAndView(){
      	ModelAndView mv = new ModelAndView();
      	//在数据库中查询到的张三的信息
      	User user = new User();
      	user.setName("张三");
      	user.setPassword("123456");
      	user.setAge(20);
      	//存放到域对象中
      	mv.addObject("user",user);
      	//设置指向的页面
      	mv.setViewName("success");
      	return mv;
      }
      

5.2 SpringMVC提供的转发和重定向关键字

  • 如果不想使用视图解析器,而且控制器方法的返回值还是String类型的,怎么办??

  • 通过Spring提供的两个关键字,可以实现支付串拼接的转发或者重定向

    • 转发关键字:" forward: 路径 "
      • **它相当于 request.getRequestDispatcher(“url”).forward(request,response) **
      • **使用请求转发,既可以转发到 jsp,也可以转发到其他的控制器方法 **
    • 重定向关键字:" redirect: 路径 "
      • **它相当于 response.sendRedirect(url) **
      • 需要注意的是,如果是重定向到 jsp 页面,则 jsp 页面不能写在 WEB-INF 目录中,否则无法找到。
  • 案例源码:

    • <a href="user/textSpringMVCForward">SpringMVC关键字进行转发</a>
      <a href="user/textSpringMVCRedirect">SpringMVC关键字进行重定向</a>
      --------------------------------------------------------------------------------
      	//SpringMVC关键字进行转发
      	@RequestMapping("/textSpringMVCForward")
      	public String textSpringMVCForward(){
      		System.out.println("SpringMVC关键字进行转发方法执行了");
      		return "forward:/WEB-INF/pages/success.jsp";
      	}
      
      	//SpringMVC关键字进行重定向
      	@RequestMapping("/textSpringMVCRedirect")
      	public String textSpringMVCRedirect(){
      		System.out.println("SpringMVC关键字进行重定向方法执行了");
      
      		return "redirect: /WEB-INF/pages/success.jsp";
      	}
      

5.3 ResponseBody响应 JSON 数据

1、(重点) DispatcherServlet控制器会拦截静态资源,导致一个问题
  • 问题的分析:

    • DispatcherServlet会拦截到所有的资源(可以看一下控制器的配置),导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。
  • 问题的解决:

    • 需要配置静态资源不进行拦截,在SpringMVC.xml配置文件添加如下配置
  • 如何配置:

    • 在SpringMVC.xml文件上进行配置 < mvc:resources/>标签

      • < mvc:resources/>标签

        • location属性: 在webapp目录下的包下的静态资源的位置
        • mapping属性: /static开头的所有请求路径,静态资源的请求路径,如/static/a 或者/static/a/b
      • 常用的通用模板:

        • <mvc:resources location="/css/" mapping="/css/**"/>
          <mvc:resources location="/images/" mapping="/images/**"/>
          <mvc:resources location="/js/" mapping="/js/**"/>
          
  • 参考其他处理方式:

2、发送json数据请求,并使用@RequestBody获取json数据

​ (先导入JQuery的静态资源,或者在Maven的坐标中导入JQuery)

<!--通过ajax发送请求数据 -->
<%--按钮--%>
<input id="button" type="button" value="发送请求"/>
<%--引入JQuery--%>
<script type="text/javascript" class="/js/jquery-3.5.1.min.js"></script>
<%--发送ajax--%>
<script>
      $("#button").click(function (){
          $.ajax({
              url: "user/textJson",
              contentType:"application/json;charset=UTF-8",
              data:{"name":"张三","password":"12345","age":18},
              dataType:"json",
              type:"post",
              success:function (data) {
                  //服务器对返回的json数据进行处理
                  alert(data);
              }
          });
      });
</script>
//控制器方法
@RequestMapping("/textJson")
//将整个json请求体都封装到body参数中去(通过@RequestBody注解)
public String textJson(@RequestBody String body){
   System.out.println(body);
   return "success";
}
3、 json字符串和JavaBean对象互相转换的过程中,需要使用jackson的jar包

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>
4、怎么把发送过来的Json数据,封装到相应的对象中??
  • SpringMVC帮我们提供了Json数据转为JavaBean对象,但是要导入Jackson的jar包

  • 通过@RequestBody注解,在控制器的参数直接把数据传给对应的对象

  • @RequestMapping("/textJson")
    //@RequestBody注解,将整个json请求体都封装到body参数中去
    //我们得到Json可以可以通过java的API进行对数据的解析
    //SpringMVC会自动帮我们封装到响应的对象中(前提是json中的键的名称和对象的属性名相同)
    public String textJson(@RequestBody User user){
       System.out.println(user);
       return "success";
    }
    
5、 使用@ResponseBody注解把JavaBean对象转换成json字符串,直接响应
  • 在返回值上加上 @ResponseBody 注解把返回值类型的对象,转为Json的格式返回去

  • //@ResponseBody注解,会把返回舱去的User对象数据,转为Json的格式
    public @ResponseBody User textJson3(@RequestBody User user){
       System.out.println(user);
       User newUser = new User();
       newUser.setName("李四");
       newUser.setAge(22);
       newUser.setPassword("56789");
       return newUser;
    }
    



第六章 文件的上传

1、传统方式文件上传回顾

  • 导入上传文件的jar包

    • <!--上传文件的jar包-->
      <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>
      
  • 表单上传文件的要求:

    • form 表单的 enctype 取值必须是:multipart/form-data

      • 默认的application/x-www-form-urlencoded是以键值对的方式上传
      • multipart/form-data 是以分段的形式上传文件
    • (默认值是:application/x-www-form-urlencoded)

    • enctype:是表单请求正文的类型

    • <form action="user/textFileUpload" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload"><br/>
        <input type="submit" value="提交">
      </form>
      
  • Servlet控制器的处理:

    • @RequestMapping("/textFileUpload")
      public String textFileUpload(HttpServletRequest request) throws Exception {
         System.out.println("文件上传");
         //1、文件上传的位置
      
         //1、1拿到要上传文件夹的路径
         String path = request.getSession().getServletContext().getRealPath("/uploads/");
         //1、2判断该路径是否存在??
         File file = new File(path);
         if (!file.exists()) {
            //不存在的话,创建该目录
            file.mkdirs();
         }
          
         //2、解析request对象,获取到上传的文件项(根据提供的jar包解析)
         //2、1创建磁盘文件项工厂
         DiskFileItemFactory factory = new DiskFileItemFactory();
         ServletFileUpload upload = new ServletFileUpload(factory);
         //2、2解析request(里面全是放的文件项),完成文件的上传
         List<FileItem> items = upload.parseRequest(request);
         //遍历文件项
         for (FileItem item : items) {
            //拿到每一个文件项,进行判断,判断当前的文件项是否是上传文件项
            //判断文件项是普通字段,还是上传的文件
            if (item.isFormField()) {
               //如果是true说明是一个普通的表单项
            } else {
               //如果是false说明是一个上传文件项
               //拿到上传文件的名(注意同名文件会把文件替换了)
               String fileName = item.getName();
               //把文件名称设置为唯一值uuid
               String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
               fileName=fileName+uuid;
               //完成文件的上传
               item.write(new File(path, fileName));
               //删除临时文件
               item.delete();
            }
         }
         return "success";
         }
      

2、SpringMVC方式的文件上传

2.1 原理:

  • 通过文件解析器(MultipartFile对象)的一个组件
  • 在控制器的参数中,传入文件解析器对象
  • 注意:表单的name名称控制器中文件上传项参数名 必须一样
  • 在这里插入图片描述

2.2 配置文件解析器对象

  • 在SpringMVC.xml文件中配置其Bean对象

  • 在该Bean对象中可以设置很多的上传要求:最大文件大小(maxUploadSize)等等

  • 注意文件解析器的id必须为:multipartResolver

    • <!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <property name="maxUploadSize" value="10485760"/>
      </bean>
      

2.3 源码:

  • jsp代码:

      <form action="user/textSpringMVCFileUpload" method="post" enctype="multipart/form-data">
        <h3>SpringMVC方式文件上传</h3>
        选择文件:<input type="file" name="upload"><br>
        <input type="submit" value="提交">
      </form>
    
  • 控制器源码:

    • @RequestMapping("/textSpringMVCFileUpload")
      public  String textSpringMVCFileUpload(HttpServletRequest request,MultipartFile upload) throws IOException {
         //1、文件上传的位置
         //1、1拿到要上传文件夹的路径
         String path = request.getSession().getServletContext().getRealPath("/uploads/");
         //1、2判断该路径是否存在??
         File file = new File(path);
         if (!file.exists()) {
            //不存在的话,创建该目录
            file.mkdirs();
         }
         //不用再自己进行解析文件了,拿到的upload就是SpringMVC的文件解析器已将帮忙解析好的文件
         //拿到上传的名称
         String filename = upload.getOriginalFilename();
         //把名字设为唯一值(通过uuid方式,也可以使用时间戳)
         String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
         filename=uuid+"-"+filename;
         //完成文件的上传
         upload.transferTo(new File(path,filename));
         //临时文件SpringMVC帮我们自动删除了
         return "success";
      }
      

3、SpringMVC跨服务器方式的文件上传

3.1 分服务器的目的??

  • 在实际开发中,我们会有很多处理不同功能的服务器。
  • 例如:
    • 应用服务器:负责部署我们的应用
    • 数据库服务器:运行我们的数据库
    • 缓存和消息服务器:负责处理大并发访问的缓存和消息
    • 文件服务器:负责存储用户上传文件的服务器。
    • ( 注意:此处说的不是服务器集群)
  • 分服务器处理的目的是让服务器各司其职,从而提高我们项目 的运行效率
  • 在这里插入图片描述
  • 在这里插入图片描述

3.2 所需要的的jar包两个服务器的准备(搭建环境)

  • 需要的jar包:

    • 在这里插入图片描述

    • 对应的Maven的坐标

      • <!--跨服务器方式上传-->
        <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>
        
  • 创建两个服务器

    • 创建一个存放图片的项目,部署到一个服务器上(图片服务器)
    • 创建另一个项目(写源码的项目),部署到服务器上(应用服务器)

3.3 SpringMVC跨服务器上传文件源码

  • 前端jsp页面:

    • <form action="user/textSpringMVCSericerFileUpload" method="post" enctype="multipart/form-data">
        <h3>SpringMVC跨服务器方式文件上传</h3>
        选择文件:<input type="file" name="upload"><br>
        <input type="submit" value="提交">
      </form>
      
  • 控制器:

    • @RequestMapping("/textSpringMVCSericerFileUpload")
      public  String textSpringMVCSericerFileUpload(MultipartFile upload) throws Exception{
      
         //定义上传服务器的路径(注意:后面写个斜杠,进行分离)
         //传到改路径下
         String path="http://localhost:9090/springmvc_image/uploads";
         //上传文件名称
         String filename = upload.getOriginalFilename();
         //名称唯一
         String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
         filename=uuid + "-"+filename;
         //使用导入的jar包,完成跨服务器的上传
         //1、创建客户端的对象
         Client client = Client.create();
         //2、与图片服务器进行连接
         WebResource webResource = client.resource(path + filename);
         //3、调用方法上传文件
         webResource.put(upload.getBytes());
         return "success";
      }
      

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小镇男孩~~

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值