Spring|SpringMVC的请求和响应以及文件上传

一、SpringMVC的数据响应

1.1 SpringMVC的数据响应方式

1)页面跳转

  • 直接返回字符串
  • 通过ModelAndView对象返回

2)回写数据

  • 直接返回字符串
  • 返回对象或集合

1.2 页面跳转

1) 返回字符串形式
在这里插入图片描述
2) 返回 ModelAndview对象

在UserController中设置视图名称

@RequestMapping(value = "/quick2")
public ModelAndView save2() {
	   /*
	    * Model:模型 作用:封装数据
	    * View: 视图 作用:展示数据
	    * */
	   ModelAndView modelAndView = new ModelAndView();
	   //设置视图名称
	   modelAndView.setViewName("success");
	   return modelAndView;
}

访问http://localhost:8080/user/quick2测试
在这里插入图片描述
在UserController中设置模型数据

@RequestMapping(value = "/quick2")
public ModelAndView save2() {
	   /*
	    * Model:模型 作用:封装数据
	    * View: 视图 作用:展示数据
	    * */
	   ModelAndView modelAndView = new ModelAndView();
	   //设置模型数据
	   modelAndView.addObject("username","zhangsan");//可以为对象,集合等
	   //设置视图名称
	   modelAndView.setViewName("success");
	   return modelAndView;
}

编写jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success! ${username}</h1>
</body>
</html>

访问http://localhost:8080/user/quick2
在这里插入图片描述
使用springmvc提供的modelAndView

@RequestMapping(value = "/quick3")
public ModelAndView save3(ModelAndView modelAndView) {
	   //设置模型数据
	   modelAndView.addObject("username","lisi");
	   //设置视图名称
	   modelAndView.setViewName("success");
	   return modelAndView;
}

访问http://localhost:8080/user/quick3
在这里插入图片描述
使用springmvc提供的model

@RequestMapping(value = "/quick4")
public String save4(Model model) {
	   //设置模型数据
	   model.addAttribute("username", "wangwu");
	   return "success";
}

访问http://localhost:8080/user/quick4
在这里插入图片描述

3) 向 request存储数据

在进行转发时,往往要向 request域中存储数据,在jsp页面中显示,那么 Controller中怎样向 request域中存储数据呢?

1)通过SpringMVC框架注入的request对象setAttribute()方法设置(为了解耦合,不常用)

@RequestMapping(value = "/quick5")
public String save5(HttpServletRequest request) {
	   //设置模型数据
	   request.setAttribute("username", "zhaoliu");
	   return "success";
}

访问http://localhost:8080/user/quick5
在这里插入图片描述
2)通过ModelAndViewaddobject()方法设置

@RequestMapping(value = "/quick3")
public ModelAndView save3(ModelAndView modelAndView) {
	   //设置模型数据
	   modelAndView.addObject("username","zhaoliu");
	   //设置视图名称
	   modelAndView.setViewName("success");
	   return modelAndView;
}

在这里插入图片描述

1.3 回写数据

1)直接返回字符串

Web基础阶段,客户端访问服务器端,如果想直接回写字符串作为响应体返回的话,只需要使用response.getWriter().print(“Hello zhangsan!”);即可,那么在 Controller中想直接回写字符串该怎样呢?

通过 SpringMVC框架注入的 response对象,使用 response.getWriter().print(“Hello zhangsan!”);回写数据,此时不需要视图跳转,业务方法返回值为void。

@RequestMapping(value = "/quick6")
public void save6(HttpServletResponse response) throws IOException {
	   response.getWriter().print("Hello zhangsan!");
}

访问http://localhost:8080/user/quick6
在这里插入图片描述

以字符串方式回写数据

@RequestMapping(value = "/quick7")
public String save7(HttpServletResponse response) throws IOException {
   	return "Hello SpringMVC!";
}

访问http://localhost:8080/user/quick7
在这里插入图片描述

SpringMVC可没有那么智能 无法判断你是想回写字符串 还是 跳转视图哦,解决方法就是加上@ResponseBody

将需要回写的字符串直接返回,但此时需要通过 @ResponseBody注解告知 SpringMVC框架,方法返回的字符串不是跳转是直接在http响应体中返回。

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick7")
public String save7() {
   	return "Hello SpringMVC!";
}

再次访问http://localhost:8080/user/quick7
在这里插入图片描述

在异步项目中,客户端与服务器端往往要进行json格式字符串交互,此时我们可以手动拼接son字符串返回。

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick8")
public String save8() {
  	 return "{\"username\":\"zhangsan\",\"age\":18}";
}

访问http://localhost:8080/user/quick8
在这里插入图片描述

在上述方式手动拼按json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串我们可以使用json转换工具 jackson进行转换。

2)返回对象或集合

导入 jackson相关坐标。

<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-databind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

domain中的User

public class User {
    private String username;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
        @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}

将对象转换成json字符串返回

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick9")
public String save9() throws Exception {
    User user = new User();
    user.setUsername("lisi");
    user.setAge(30);
    //使用json的转换工具将对象转化为json格式字符串在返回
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(user);
    
    return json;
}

注意返回是也是字符串并不是视图! 所以要加上@ResponseBody

访问http://localhost:8080/user/quick9
在这里插入图片描述

到这里,又有新问题了,就是每次都要new ObjectMapper(); 然后为我们转化称为json字符串,但是开发的主要思想是什么?就是尽量达到代码的复用,代码不要冗余,解耦合,为了进一步展现这种开发理念,所以自然SpringMVC为我们做好了这一切,但是需要我们手动进行配置才行。

想到之前翻阅DispatcherServlet.properties
看到InternalResourceViewResolver于是想进一步拜读源码,再次阅读发现了RequestMappingHandlerAdapter(处理器适配器)

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

进一步翻阅RequestMappingHandlerAdapter源码,在214行有这样一段代码

//设置消息转换器 可以自己指定一个json转换器
public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
    this.messageConverters = messageConverters;
}

想到之前在spring-mvc.xml中配置过内部资源视图解析器,我们在spring-mvc.xml中配置的目的就是要对其中一些默认的参数进行设置(干预),springmvc并不知道我们需要转成json格式,所以需要我们去手动设置。

spring-mvc.xml配置处理器适配器

通过 SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用 jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行如下配置:

<!--    配置处理器映射器-->
<bean id="requestMappingHandlerAdapter"
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
        </list>
    </property>
</bean>

编写测试类

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick10")
//期望SpringMVC自动将User转换成json格式的字符串
public User save10() throws Exception {
    User user = new User();
    user.setUsername("wangwu");
    user.setAge(26);

    //直接返回对象 利用springmvc自动为我们转换为json字符串
    return user;
}

注:@ResponseBody还需要写上,spring-mvc.xml只是对转化为json做了封装,实际上返回的还是字符串。

访问http://localhost:8080/user/quick10
在这里插入图片描述

在方法上添加@ ResponseBody就可以返回json格式的字符串,但是这样配置还是比较麻烦,配置的代码比较多因此,我们该如何进一步优化呢?那么我们使用mvc的注解驱动就代替上述配置。

<!--mvc的注解驱动-->
<mvc:annotation-driven/>

这里介绍一下:在 SpringMVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为SpringMVC的三大组件。
使用<mvc:annotation-driven>自动加载 RequestMapping HandlerMapping(处理映射器)和RequestMappingHandlerAdapter(处理适配器),可用在 Spring-mvc.xml配置文件中使用
<mvc:annotation-driven/>替代注解处理器和适配器的配置。

(重点)同时使用<mvc:annotation -driven>默认底层就会集成jackson进行对象或集合的json格式字符串的转换

注:要使用<mvc:annotation -driven>必须引入mvc的命名空间

xmlns:mvc="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd

再次访问http://localhost:8080/user/quick10
在这里插入图片描述

1.4 小结

1)页面跳转

  • 直接返回字符串
  • 通过ModelAndView对象返回

2)回写数据

  • 直接返回字符串
  • 返回对象或集合

二、SpringMVC获得请求数据

2.1 获得请求参数

客户端请求参数的格式是:name= value&name= value…
服务器端要获得请求的参数,有时还需要进行数据的封装, Spring MVC可以接收如下类型的参数:

  • 基本类型参数
  • POJO类型参数(简单JavaBean)
  • 数组类型参数
  • 集合类型参数

2.2 获得基本类型参数

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick11")
public void save11(String username,int age){
    System.out.println(username);
    System.out.println(age);
}

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。

访问http://localhost:8080/user/quick11?username=zhangsan&age=18因为没有return所以浏览器页面没有数据回显(响应体空白),控制台输出结果:
在这里插入图片描述

2.3 获得POJO类型参数

原来我们要把请求数据封装到实体中,数据->到达服务端->在doGET/doPOST方法当中,使用getParameterMap,然后用 BeanUtil进行实体的封装,而这些操作也已经被我们优秀的SpringMVC框架底层做了封装!我们只要遵循它所提供的规则来使用就可以啦~

Controller中的业务方法的POJO参数的属性名与请求参数的ηame一致,参数值会自动映射匹配。

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick12")
public void save12(User user){
    System.out.println(user);
}

访问http://localhost:8080/user/quick12?username=zhangsan&age=18控制台输出:
在这里插入图片描述

2.4 获得数组类型参数

Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick13")
public void save13(String[] strs){
    System.out.println(Arrays.asList(strs));
}

访问http://localhost:8080/user/quick13?strs=aaa&strs=bbb&strs=ccc控制台输出:
在这里插入图片描述

2.5 获得集合类型参数

获得集合参数时,要将集合参数包装到一个POJO中才可以。

编写封类VO(ViewObject视图对象 || ValueObject值对象)

public class VO {
    private List<User> userList;

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    @Override
    public String toString() {
        return "VO{" +
                "userList=" + userList +
                '}';
    }
}

vo接受的参数就是userList

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick14")
public void save14(VO vo) {
    System.out.println(vo);
}

编写提交表单的jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${[pageContext.request.contextPath]}/user/quick14" method="post">
    <%--表明是第几个对象的username age--%>
    <input type="text" name="userList[0].username"></br>
    <input type="text" name="userList[0].age"></br>
    <input type="text" name="userList[1].username"></br>
    <input type="text" name="userList[1].age"></br>
    <input type="submit">
</form>
</body>
</html>

访问http://localhost:8080/form.jsp
在这里插入图片描述
提交表单数据
在这里插入图片描述

2.5 获得集合类型参数

当使用ajax提交时,可以指定 contentType为son形式,那么在方法参数位置使用@ RequestBody可以直接接收集合数据而无需使用POJO进行包装。

使用ajax发送POST请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
    <script>
        var userList = new Array();
        userList.push({username:"zhangsan",age:"18"});
        userList.push({username:"lisi",age:"20"});
        $.ajax({
            type:"POST",
            url:"${pageContext.request.contextPath}/user/quick15",
            data:JSON.stringify(userList),
            contentType:'application/json;charset=utf-8'
        });
    </script>
</head>
<body>

</body>
</html>

浏览器控制台报错
在这里插入图片描述

注意:通过chrome调试工具,发现没有加载到 jquery文件,原因是 SpringMVC的前端控制器DispatcherServlet的url- pattern配置的是/代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源在 spring-mvc.xml配置文件中指定放行的资源
<mvc:resources mapping="/js/**" location="/js/"/>
使用<mvc:default-servlet-handler/>标签

解决方法:

spring-mvc中配置如下代码

<!--    开放资源的访问权限-->
<!--    mapping是访问服务端找资源的地址 location具体资源所在路径    -->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/img/**" location="/img/"/>

这样报错问题就解决啦~
在这里插入图片描述
通过浏览器抓包可以看到一共发送了3次请求
在这里插入图片描述
使用<mvc:default-servlet-handler/>

<!--    企业中常用的配置方法-->
<!--    代表spring-mvc框架如果无法找到对应资源 交给原始的tomcat去寻找对应的资源返回-->
<mvc:default-servlet-handler/>

注:
静态资源访问时开放访问权限的两种方法:
方法一(繁琐):配置<mvc:resources mapping="/js/**" location="/js/"/>
方法二(常用):配置<mvc:default-servlet-handler/>

2.6 请求数据乱码问题

刚才我们提供的表单数据都是拼音,并没有提交汉字,那么提交中文汉字会怎么样呢?

在这里插入图片描述

毫无疑问POST发送的请求乱码了,因为我们没有设置对应的编码格式,但是我们现在又不能像之前那样设置
resquest.setCharacterEncoding();了因为我们开发的理念就是无限解耦合下去,能解耦合就解耦合,不要都写在一个文件当中。那么如何解决呢?往下看!

当post请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤。

web.xml中配置过滤器:

<!--配置全局过滤的Filter-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

再次提交表单数据:
在这里插入图片描述

注:
GET的请求方式不会出现乱码问题,因为Tomcat8.5的服务器已经帮我们解决好了。
POST请求需要我们设置一个过滤器来进行编码的过滤。

2.7 参数绑定注解@requestParam(常用)

当请求的参数名称与 Controller的业务方法参数名称不一致时,就需要通过@ RequestParam注解显示的绑定,什么意思呢?接下来演示一下。

访问http://localhost:8080/user/quick16?username=zhangsan

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick16")
public void save16(String username) {
    System.out.println(username);
}

控制台输出:
在这里插入图片描述

但是如果携带的参数不是username而是name呢?

访问http://localhost:8080/user/quick16?name=zhangsan
控制台输出:
在这里插入图片描述

那如何解决呢?我想让参数是name时也能拿到请求参数,如何做呢?那就是使用参数绑定注解@requestParam

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick16")
public void save16(@RequestParam("name") String username) {
    System.out.println(username);
}

注:
如果参数只有一个,默认表示的就是Value(最重要的值)

访问http://localhost:8080/user/quick16?name=zhangsan
控制台输出:
在这里插入图片描述

到这里就达成了参数是name还可以拿到参数的值啦!

同时注解@RequestParam还有如下参数可以使用:

  • value:与请求参数名称
  • required:此在指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错
  • defaultvalue:当没有指定请求参数时,则使用指定的默认值赋值

1)value

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick16")
public void save16(@RequestParam(value = "name") String username) {
    System.out.println(username);
}

2)required
没写required默认的是true

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick16")
public void save16(@RequestParam(value = "name") String username) {
    System.out.println(username);
}

未携带参数访问http://localhost:8080/user/quick16报错如下:
在这里插入图片描述
携带参数访问http://localhost:8080/user/quick16?name=zhangsan正常不报错。

设置成required = false

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick16")
public void save16(@RequestParam(value = "name", required = false) String username) {
    System.out.println(username);
}

未携带参数访问http://localhost:8080/user/quick16也不会报错

3)defaultvalue

@RequestMapping(value = "/quick16")
public void save16(@RequestParam(value = "name", defaultValue ="Hello SpringMVC") String username) {
    System.out.println(username);
}

未携带参数访问http://localhost:8080/user/quick16控制台输出:
在这里插入图片描述

携带参数访问http://localhost:8080/user/quick16?name=HelloZhangsan控制台输出:
在这里插入图片描述

2.8 获得 Restful风格的参数

Restful是—种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。

Restful风格的请求是使用"url+请求方式”表示一次请求目的的,HTTP协议里面四个表示操作方式的动词如下

  • GET用于获取资源
  • POST:用于新建资源
  • PUT:用于更新资源
  • DELETE:用于删除资源

    例如:
  • /user/1 GET: 得到id=1的user
  • /user/1 DELETE:删除id=1的user
  • /use/1PUT:更新id=1的user
  • /user POST:新增user

上述ur地址/user/1中的1就是要获得的请求参数,在 SpringMVC中可以使用占位符进行参数绑定。地址/user/1可以写成/user/{id},占位符{id对应的就是1的值。在业务方法中我们可以使用@Pathvariable注解进行占位符的匹配获取工作。

//localhost:8080/user/quick17/zhangsan
@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick17/{username}")
public void save17(@PathVariable(value = "username") String username) {
    System.out.println(username);
}

在这里插入图片描述
访问http://localhost:8080/user/quick17/zhangsan控制台打印输出:
在这里插入图片描述

2.9 自定义类型转换器

SpringMVC默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置
但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日眀类型的数据就需要自定义转换器。

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick18")
public void save18(Date date) {
    System.out.println(date);
}

访问http://localhost:8080/user/quick18?date=2021/2/19控制台输出:
在这里插入图片描述
访问http://localhost:8080/user/quick18?date=2021-2-19则报错
在这里插入图片描述

辣么该怎么办呢?这时就需要我们自定义类型转换器了。

自定义类型转换器的开发步骤
①定义转换器类实现 Converter接口
②在配置文件中声明转换器
③在<annotation-driven>中引用转换器

1)定义转换器类实现 Converter接口

//String原始字符串 Date要转换成的类型 从第一个参数 转换到 第二个参数
public class DateConverter implements Converter<String, Date> {
    public Date convert(String dateStr) {
        //将日期字符串转换成为日期对象 返回
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

2)在spring-mvc.xml文件中声明转换器

<!--    声明转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="com.itheima.converter.DateConverter"></bean>
        </list>
    </property>
</bean>

3)在<annotation-driven>中引用转换器

<mvc:annotation-driven conversion-service="conversionService"/>

再次访问http://localhost:8080/user/quick18?date=2021-2-19
在这里插入图片描述

2.10 获得 Servlet相关API

SpringMVO支持使用原始 Servletapl对象作为控制器方法的参数进行注入,常用的对象如下

  • Http servletrEquest
  • Http servletrEsponse
  • Httpsession

测试代码:

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick19")
public void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
}

访问http://localhost:8080/user/quick19控制台输出:
在这里插入图片描述

2.11 获得请求头

1)@RequestHeader

使用@ Cookievalue可以获得指定 Cookie的值
@ Cookievalue注解的属性如下value:指定 cookie的名称required:是否必须携带此 cookie

测试代码:

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick20")
public void save20(@RequestHeader(value = "User-Agent", required = false) String user_agent) {
    System.out.println(user_agent);
}

使用chrome的调试工具抓包查看Request Headers
在这里插入图片描述

访问http://localhost:8080/user/quick20控制台输出:
在这里插入图片描述

2)@CookieValue

使用@ Cookievalue可以获得指定 Cookie的值
@ Cookievalue注解的属性如下

  • vaue:指定 cookie的名称
  • required:是否必须携带此 cookie

编写测试代码

@ResponseBody //告知SpringMVC框架 不进行视图的跳转 直接进行数据响应
@RequestMapping(value = "/quick21")
public void save21(@CookieValue(value = "JSESSIONID", required = false) String jsessionId) {
    System.out.println(jsessionId);
}

访问http://localhost:8080/user/quick21

浏览器中的信息:
在这里插入图片描述
控制台输出的信息:
在这里插入图片描述

三、文件上传

1)文件上传客户端三要素

  • 表单项type="fle
  • 表单的提交方式是post
  • 表单的 enctype属性是多部分表单形式,及 enctype=" multipart/ form-data

在这里插入图片描述

2)文件上传原理

  • 当form表单修改为多部分表单时, request.getParameter将失效。
  • enctype=" application/x-www- form-urlencoded"时,form表单的正文内容格式是:
    key=value&key=value&key=value
  • 当form表单的 enctype取值为 Mutilpart/form-data时,请求正文内容就变成多部分形式:

在这里插入图片描述

3.1 单文件上传实现

①导入fileupload和io坐标
②配置文件上传解析器
③编写文件上传代码

1)在pom.xml中导入fileupload和io坐标

<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.3</version>
</dependency>

2)在spring-mvc.xml配置文件上传解析器

<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 上传文件总大小-->
    <property name="maxUploadSize" value="5242800"/>
    <!-- 上传单个文件的大小-->
    <property name="maxUploadSizePerFile" value="5242800"/>
    <!--上传文件的编码类型-->
    <property name="defaultEncoding" value="UTF-8"/>
</bean>

3)编写文件上传代码
upload.jsp代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/user/quick22" method="POST" enctype="multipart/form-data">
        名称<input type="text" name="username"><br/>
        文件<input type="file" name="uploadFile"><br/>
        <input type="submit" value="提交"><br/>
    </form>
</body>
</html>

编写文件上传代码:

@RequestMapping(value = "/quick22")
public void save22(String username, MultipartFile uploadFile) {
    System.out.println(username);
    System.out.println(uploadFile);
}

注:此处的MultipartFile uploadFile必须与<input type="file" name="uploadFile">中的name保持一致

访问http://localhost:8080/upload.jsp并提交表单:
在这里插入图片描述
控制台输出:
在这里插入图片描述

表明文件上传成功啦!

编写文件上传代码,上传到本地磁盘F:\upload中

@RequestMapping(value = "/quick23")
public void save23(String username, MultipartFile uploadFile) throws IOException {
    System.out.println(username);
    //获得上传文件的名称
    String originalFilename = uploadFile.getOriginalFilename();
    uploadFile.transferTo(new File("F:\\upload\\" + originalFilename));
}

发现F盘下的upload中多了上传的文件即为成功!

3.2 多文件上传实现

方法一:
使用多个name

<form action="${pageContext.request.contextPath}/user/quick22" method="POST" enctype="multipart/form-data">
    名称<input type="text" name="username"><br/>
    文件1<input type="file" name="uploadFile1"><br/>
    文件2<input type="file" name="uploadFile2"><br/>
    <input type="submit" value="提交"><br/>
</form>
@RequestMapping(value = "/quick23")
public void save23(String username, MultipartFile uploadFile1, MultipartFile uploadFile2) throws IOException {
    System.out.println(username);
    //获得上传文件的名称
    String originalFilename1 = uploadFile1.getOriginalFilename();
    uploadFile1.transferTo(new File("F:\\upload\\" + originalFilename1));
    String originalFilename2 = uploadFile2.getOriginalFilename();
    uploadFile1.transferTo(new File("F:\\upload\\" + originalFilename2));
}

方法二:将方法参数 MultipartIte类型修改为 MultipartFilel[]即可

<form action="${pageContext.request.contextPath}/user/quick22" method="POST" enctype="multipart/form-data">
    名称<input type="text" name="username"><br/>
    文件1<input type="file" name="uploadFile"><br/>
    文件2<input type="file" name="uploadFile"><br/>
    <input type="submit" value="提交"><br/>
</form>
@RequestMapping(value = "/quick24")
public void save24(String username, MultipartFile[] uploadFile) throws IOException {
    System.out.println(username);
    //获得上传文件的名称
    for (MultipartFile multipartFile : uploadFile) {
        String originalFilename = multipartFile.getOriginalFilename();
        multipartFile.transferTo(new File("F:\\upload\\" + originalFilename));
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring MVC请求响应主要通过 HttpServletRequest 和 HttpServletResponse 对象来实现。 HttpServletRequest 对象代表客户端的请求,它包含了客户端发送请求信息,比如请求方式、请求 URL、请求参数等。HttpServletRequest 对象可以通过方法参数传递到请求处理方法中,也可以通过注解 @Autowired 自动注入到控制器中。 HttpServletResponse 对象代表服务器的响应,它包含了服务器返回的响应信息,比如响应状态码、响应头、响应正文等。HttpServletResponse 对象可以通过方法参数传递到请求处理方法中,使用它可以设置响应的内容、编码、类型等。 下面是一个简单的 Spring MVC请求响应示例: ```java @Controller public class HelloController { @RequestMapping("/hello") public void hello(HttpServletRequest request, HttpServletResponse response) throws IOException { // 获取请求参数 String name = request.getParameter("name"); // 设置响应内容 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("<h1>Hello, " + name + "!</h1>"); out.println("</body></html>"); } } ``` 在上面的示例中,我们定义了一个控制器类 HelloController,它包含一个请求处理方法 hello,该方法接收 HttpServletRequest 和 HttpServletResponse 对象作为参数。在请求处理方法中,我们通过 HttpServletRequest 对象获取请求参数 name,然后通过 HttpServletResponse 对象设置响应编码和类型,并输出响应内容。 在 Spring MVC 中,我们也可以使用 @RequestParam 注解来简化获取请求参数的过程,使用 @ResponseBody 注解来简化设置响应内容的过程。例如: ```java @Controller public class HelloController { @RequestMapping("/hello") @ResponseBody public String hello(@RequestParam("name") String name) { return "Hello, " + name + "!"; } } ``` 在上面的示例中,我们使用 @RequestParam 注解来获取请求参数 name,使用 @ResponseBody 注解来设置响应内容,并返回一个字符串作为响应结果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值