SpringMVC(三) Controller返回值、Ajax交互、文件上传

1. Controller方法(Handler)的返回值

1.1 返回ModelAndView

  • 若处理器对请求处理过后,不仅要进行跳转,而且在跳转过程中还要传递数据,此时使用ModelAndView较为方便。
  • 在控制器类中,处理客户端请求后,可以把需要响应到页面的数据和视图名字都封装到一个ModelAndView对象中,然后直接返回这个ModelAndView对象。
  • 示例代码如下,将时间数据保存到ModelAndView对象,并传递到result.jsp页面。
@Controller
public class DefaultController {
    /**
     * 定义方法, 相当于以前Servlet中用于处理请求的方法
     */
    @RequestMapping("gotoResult")
    public ModelAndView gotoResult(ModelAndView modelAndView){
        // 封装数据
        modelAndView.addObject("nowDate",new Date());
        //指定页面
        modelAndView.setViewName("result");
        return modelAndView;
    }
}

1.2 返回字符串

  • 直接返回逻辑视图名,数据使用Model和ModelMap封装;
  • ModelAndView = ModelMap+ view(逻辑视图名);
  • 现在直接将逻辑视图名以字符串形式return(文件名);
  • Model接口方法 addAttribute(String key,Object value)存储键值对,将被存储到request域中,示例代码如下:
 /**
     *  返回字符串,返回视图逻辑名,文件名
     *  Model接口封装数据
     *  键值对存储request域对象
     */
    @RequestMapping("gotoResultModel")
    public String gotoResultModel(Model model){
        //封装数据
        model.addAttribute("nowDate", new Date()+"====gotoResultModel");
        //指定页面
        return "result";
    }
  • ModelMap封装数据,方法addAttribute(String key,Object value)存储键值对,将被存储到request域中
/**
 *  返回字符串,返回视图逻辑名,文件名
 *  ModelMap类封装数据
 *  键值对存储request域对象
 *  ModelMap类有获取的方法,而Model接口没有
 */
    @RequestMapping("gotoResultModelMap")
    public String gotoResultModelMap(ModelMap modelMap){
        //封装数据
        modelMap.addAttribute("nowDate", new Date()+"====gotoResultModelMap");
        //指定页面
        return "result";
    }
  • 使用转发进行页面跳转
    @RequestMapping("gotoResultForward")
    public String gotoResultForward(ModelMap modelMap){
        modelMap.addAttribute("nowDate",new Date()+"====gotoResult");
        return "forward:/default/gotoResultModelMap.do";
    }
  • 使用重定向进行页面跳转
@RequestMapping("gotoResultRedirect")
    public String gotoResultRedirect(ModelMap modelMap){
        modelMap.addAttribute("nowDate",new Date()+"====gotoResult");
        return "redirect:/default/gotoResultModelMap.do";
    }

1.3 没有返回值

  • request对象实现转发
    /**
     * 返回值为void类型, 使用Request对象 实现页面跳转(注意: 无法将SpringMVC 提供的Model, ModelMap封装的数据 请求转发到目标页面)
     */
    @RequestMapping("gotoResultRequest")
    public void gotoResultRequest(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过SpringMVC框架把封装数据到Request域中( 跳转页面的方式必须采用的是SpringMVC框架提交的方式, 才能把数据 传递过去 )
        modelMap.addAttribute("nowDate", new Date()+"====gotoResultRequest");
        //request.setAttribute("键", "值");
         //指定页面,请求转发
    	request.getRequestDispatcher("/default/gotoResultModelMap.do").forward(request, response);
    }
  • response对象实现重定向
 /**
     * 返回值为void类型, 使用Response跳转页面 (注意: 无法将SpringMVC 提供的Model, ModelMap封装的数据 重定向到目标页面)
     */
    @RequestMapping("gotoResultResponse")
    public void gotoResultResponse(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过SpringMVC框架把封装数据到Request域中( 跳转页面的方式必须采用的是SpringMVC框架提交的方式, 才能把数据 传递过去 )
        modelMap.addAttribute("nowDate", new Date()+"====gotoResultResponse");
        //指定页面,重定向
        //response.sendRedirect("http://localhost:8080/default/gotoResultModelMap.do");
        response.sendRedirect(request.getContextPath()+"/default/gotoResultModelMap.do");
    }
  • response对象响应字符串
/**
 * 直接使用response对象响应字符串
 */
@RequestMapping("gotoResultResponseSendString")
public void gotoResultResponseString(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.getWriter().print("Hello MVC");
}

2. Json格式数据实现Ajax交互

  • 交互:前端和后端的互动

  • 前端传递json字符串到后台,后台通过@RequestBody注解,将json字符串转换为pojo对象

    • @RequestBody注解作用:用于获取请求体(按照http协议进行一个完整的封装,往往都是由请求头+请求体等组成)内容,不适用于Get请求方式
  • 后端返回对象,前端通过@ResponseBody注解直接接收到json格式的字符串

    • @ResponseBody注解作用:该注解用于将Controller的方法返回的对象转换为json字符串返回给客户端

2.1 @RequestBody注解示例

  • 前端index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
    <%--导入js文件--%>
    <script src="js/vue.js"></script>
    <script src="js/axios-0.18.0.js"></script>
</head>
<body>
    SpringMVC框架的进行 Ajax 交互

    <fieldset>
        <h4>Ajax 的Json数据</h4>
        <div id="app">
            <input type="button" @click="clickMe()" value="发送Ajax数据">
            <%--使用插值表达式--%>
            {{ userList }}
        </div>
    </fieldset>
</body>
</html>
<script>
    <!-- 创建一个Vue对象 -->
    new Vue({
        el: '#app',
        data:{
            userList: []
        },
        methods:{
            clickMe:function(){

                var params = {id:1, username:'你好', sex:'男'};
                //发起ajax
               axios.post("/ajax/testAjax.do", params)
                   .then(response => {
                       //成功
                       //console.log(response.data);
                       this.userList = response.data
                   }).catch(error =>{
                       //失败
                       console.dir(error);
                   });
            }
        }
    })
</script>

  • 后端接收params 数据并转换成pojo对象,pojo类太简单了就不写了,后端代码如下:
@RequestMapping("ajax")
@Controller
public class AjaxController {

    //测试Ajax的方法
    @RequestMapping("testAjax")
    public void testAjax(@RequestBody User user){
        // 打印接收的数据
        System.out.println("user = " + user);
    }
}

2.2 @ResponseBody注解示例

前端代码与2.1中的index.jsp一致,后端代码如下,注意@RestController中包含 @ResponseBody@Controller两个注解

@RequestMapping("ajax")
@RestController
public class AjaxController {

    //测试Ajax的方法
    @RequestMapping("testAjax")
    public List<User> testAjax(@RequestBody User user){
        // 打印接收的数据
        System.out.println("user = " + user);

        // 准备给客户端浏览器返回的json数据
        User user1 = new User();
        user1.setId(2);
        user1.setName("李四");
        user1.setSex("男");

        User user2 = new User();
        user2.setId(3);
        user2.setName("王五");
        user2.setSex("女");

        List<User> list = new ArrayList<User>();
        list.add(user1);
        list.add(user2);
        return list;
    }
}

3. SpringMVC实现文件上传

前提:

  1. form表单请求方式必须是post
  2. 添加form表单的参数:enctype 多部件表单类型 enctype=“multipart/form-data”
  3. 引入依赖:commons-upload, commons-io

3.1 文件上传

3.1.1 引入依赖

<!-- 引入fileUpload会自动依赖commons-io --> 
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

3.1.2 spring-mvc.xml 配置文件

<!-- 配置文件上传解析器 -->
<!-- id的值是固定的-->
<bean id="multipartResolver"
				class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设置上传文件的最大尺寸为5MB -->
		<property name="maxUploadSize">
			<value>5242880</value>
		</property>
</bean>

3.1.3 页面配置

<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="uploadFile">
        <input type="text" name="username">
        <input type="submit" value="上传">
 </form>

3.1.4 Controller层代码

@Controller
public class UploadController {

    /**
     * 本地上传
     MultipartFile接口方法:
     - String getOriginalFilename()获取上传文件名
     - byte[] getBytes()文件转成字节数组
     - void transferTo(File file)转换方法,将上传文件转换到File对象
     */
    @RequestMapping("/upload")
    public String upload(MultipartFile uploadFile, HttpServletRequest request){

        //32位的随机内容的字符串
        String uuid = UUID.randomUUID().toString().replace("-","");
        //文件名称
        String filename = uploadFile.getOriginalFilename();
        System.out.println("filename = " + filename);

        //文件上传
        String realPath = request.getSession().getServletContext().getRealPath(request.getContextPath() + "/upload");
        File path = new File(realPath, uuid+filename);
        try {
            uploadFile.transferTo(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "success";
    }
}

3.2 跨服上传

3.2.1 引入依赖

<!--引入jersey服务器的包-->
    <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.2.2 修改tomcat配置

注意:

  1. tomcat默认不能跨服上传的
  2. 在安装目录tomcat/conf/web.xml下修改
	<!--需要添加的-->
	<init-param>
    	<param-name>readonly</param-name>
    	<param-value>false</param-value>
    </init-param>

3.2.3 配置图片服务器

  1. 创建一个web项目
  2. 配置一个tomcat,与原来tomcat端口号不一致
  3. 在webapp目录下创建一个upload目录,空的文件夹不会编译,需要在upload目录添加(任意)一个文件

3.2.4 Controller代码

/**
     * 跨服上传
       MultipartFile接口方法:
        - String getOriginalFilename()获取上传文件名
        - byte[] getBytes()文件转成字节数组
     */
@Controller
public class UploadController {
    @RequestMapping("/upload")
    public String upload(MultipartFile uploadFile, HttpServletRequest request){

        //32位的随机内容的字符串
        String uuid = UUID.randomUUID().toString().replace("-","");
        //文件名称
        String filename = uploadFile.getOriginalFilename();
        System.out.println("filename = " + filename);

        //跨服务器上传
        String serverUrl = "http://localhost:8081/upload";
        //向服务器上传的客户端对象
        Client client = Client.create();
        WebResource resource = client.resource(serverUrl + "/" + uuid + filename);
        //执行上传文件到 指定的服务器
        //转出字节数组开始上传
        try {
            resource.put(String.class, uploadFile.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "success";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值