SpringMVC 04 数据响应 获取请求数据

1. SpringMVC数据响应

1.1 springMVC的数据相应方式

1.1.1页面跳转

1. 返回字符串

@RequestMapping(value = "/quick",method = RequestMethod.POST)
public String save(){
    System.out.println("save running");
    //返回success的这个字符串形式
    return "success.jsp";
}
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
//通过下面两句代码,将 "success.jsp"拼接
    <property name="prefix" value="/jsp"></property>
    <property name="suffix" value=".jsp"></property>
</bean>

得到:转发资源地址:/WEB-INF/views/index.jsp

2.返回ModelAndView对象,有以下三种方式

  • model:作用是封装数据
  • view:展示数据
    1)
@RequestMapping(value = "/quick2")
public ModelAndView save2(){
   ModelAndView modelAndView = new ModelAndView();
   //设置模型数据
   modelAndView.addObject("username","itcast");
   modelAndView.setViewName("success");
   return modelAndView;
}

2) 返回model对象,视图用jsp充当

@RequestMapping(value = "/quick3")
public String save3(Model model){
   model.addAttribute("username","王文汇");
   return "success";
}

1.1.2 回写数据

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

** 1. 直接回写字符串**

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

@RequestMapping(value = "/quick7")
public void save7(HttpServletResponse response) throws IOException {
   //在域中存数据
   response.getWriter().print("hello world");
}

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

//单纯的这种写法,spring会帮你直接拼接,就会出现找不到hello.jsp的错误
@RequestMapping(value = "/quick8")
public String save8(){
    //在域中存数据
   return "hello";
}

@RequestMapping(value = "/quick8_1")
@ResponseBody
//告知springmvc框架,该方法不进行页面跳转,直接新型数据相应
public String save8_1(){
    //在域中存数据
    return "hello";
}

(3) 返回json字符串

@RequestMapping(value = "/quick9")
@ResponseBody
//告知springmvc框架,该方法不进行页面跳转,直接新型数据相应
public String save9() throws Exception {

    User user = new User();
    user.setUsername("username");
    user.setAge(13);

    //定义json对象
    ObjectMapper objectMapper = new ObjectMapper();
    String s = objectMapper.writeValueAsString(user);
    return s;
}
2. 返回对象或集合

期望将对象类型直接转换成json格式的字符串

  • 在spring-mvc配制文件中配置处理器映射器中的RequestMappingHandlerAdapter对象
//主要还是MappingJackson2HttpMessageConverter这个转换器
<bean 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>
  • 有了上述配置,就可以直接将对象类型转换成json格式了
@RequestMapping(value = "/quick9")
@ResponseBody
    //希望springmvc自动将user转换成json格式的字符串
public String save10() throws Exception {
    User user = new User();
    user.setUsername("username");
    user.setAge(13);
    return "s";
}

但是!!! 每次需要就配置可太麻烦了,而且开发中可能会用到很多配置,所以,在映射文件中只加这一句代码就可以了!!

<mvc:annotation-driven/>

用这一句替代MappingJackson2HttpMessageConverter这个转换器

2. SpringMVC获取请求数据

2.1获得请求参数

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

  • 基本类型参数
  • POJO类型参数
  • 数组类型参数
  • 集合类型参数

2.2.1获得基本类型参数

假设有请求地址:http://localhost:8080/itheima_springmvc1/quick9?username=zhangsan&age=12
想要获取到参数即 username和age,只有springmvc框架看到一致后,才能进行自动封装

@RequestMapping(value = "/quick12")
@ResponseBody
//这里传进去的参数,必须和请求中一样
public void save12(String username,int age) {
   System.out.println(username);
   System.out.println(age);
}

2.2.2获取POJO类型的参数

同上假设有请求地址:http://localhost:8080/itheima_springmvc1/quick9?username=zhangsan&age=12

但是,这里面的username与age都是User的属性,是封装好的

public class User {
    private String username;
    private int age;
    //里面还有get set 方法

在controller中

@RequestMapping(value = "/quick12")
@ResponseBody
public void save13(User user) throws Exception {
   System.out.println(user);
}

2.2.3获取集合类型参数

情况一

创建vo类,里面定义Lisrt集合,每个集合中是一个user对象,每个user对象都有username和ahe属性

@RequestMapping(value = "/quick14")
@ResponseBody
public void save15(VO vo) throws Exception {
   System.out.println(Arrays.asList(vo));
}

集合对象比较特殊,上面的写法是直接取不出来的,可以创建一个jsp页面,通过form表单来获取

<%--
表明是第一个user对象的username
userList[0]代表了一个user对象
userList[0].username代表第一个user对象的username属性
%>
<form action="${pageContext.request.contextPath}/user/quick14" method="post">
	<input type="text" name="userList[0].username">
    <input type="text" name="userList[0].age">
    <input type="text" name="userList[1].username">
    <input type="text" name="userList[2].age">
</form>

但是,还有另外一种情况可以获取

情况二

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

在jsp页面中,首先 导入js

<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>

创建列表,存数据,写ajax请求

<script>
<%--        创建列表,存入数据--%>
    var userList=new Array();
    userList.push({username:"zhangsan",age:18});
     userList.push({username:"lisi",age:18});

    $.ajax({
       type:"POST",
       url:"${pageContext.request.contextPath}/user/quick15",
       //将userList转换为json格式
       data:JSON.stringify(userList),
       content:"application/json;charset=utf-8"
   })

</script>

在controller中

@RequestMapping(value = "/quick16")
@ResponseBody
public void save16(@RequestBody List<User> userList) throws Exception {
//@RequestBody必须加上
   System.out.println(Arrays.asList(userList));
}

这样就可以直接获取集合元素了

但是,访问时访问不到js静态资源,这时候就需要开启有两种方式

	//  第一种
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/img/**" location="/img/"/>
    //  第二种
    <mvc:default-servlet-handler/>

2.2解决乱码问题

在web.xml中配置全局过滤器,解决post方式访问时乱码问题

<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>

2.3参数绑定注解

当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定。
请求参数为name,但是conrtoller中写的是username,

@RequestMapping(value = "/quick17")
@ResponseBody
public void save17(@RequestParam(value = "name" ,required = false) String username) throws Exception {
    System.out.println(username);
}

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

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

2.4 Restful风格(了解)

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

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

  1. GET:用于获取资源
  2. POST:用于新建资源
  3. PUT:用于更新资源
  4. DELETE:用于删除资源

例如:

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

2.5自定义类型转换器

• SpringMVC 默认已经提供了一些常用的类型转换器,例如客户端提交的字符串转换成int型进行参数设置。

• 但是不是所有的数据类型都提供了转换器,没有提供的就需要自定义转换器,例如:日期类型的数据就需要自定义转换器。

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

假设,此时需要自定义时间类型转换器

  1. 自定时间转换器类,继承Converter接口,实现convert类
public class DateConverter implements Converter<String,Date> {
    @Override
    public Date convert(String s) {
        //将日期的字符串转换成日期对象,返回
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}
  1. 在spring-mvc中进行声明并注册
<!--    声明转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
           <!--    把写好的转换器加载进来-->
           <bean class="com.it.converter.DateConverter"></bean>
        </list>
    </property>
</bean>

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

2.6获取Servlet相关API

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

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
@RequestMapping("/quick16")
@ResponseBody
public void quickMethod16(HttpServletRequest request,HttpServletResponse response,
        HttpSession session){
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
}

2.7获取请求头

获取的是键值对

2.7.1@RequestHeader

使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:

  • value:请求头的名称
  • required:是否必须携带此请求头

2.8 文件上传

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

2.8.1 单文件上传的步骤

① 导入fileupload和io坐标

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
     <groupId>commons-io</groupId>
     <artifactId>commons-io</artifactId>
     <version>2.6</version>
</dependency>

② 配置文件上传解析器
在spring-mvc文件中编写文件上传解析器

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <property name="defaultEncoding" value="UTF-8"/>
   <property name="maxUploadSize" value="500000"/>
</bean>

③ 编写文件上传代码

  1. 定义jsp文件===> upload.jsp,用来上传文件用
<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="button" name="button">
</form>

2.编写测试代码

@RequestMapping(value = "/quick21/{name}")
@ResponseBody
public void save22(String username, MultipartFile uploadFile) throws Exception {
    //这里的upload必须要和jsp中文件名称一致
    System.out.println(username);
    System.out.println(uploadFile);
//        获取文件上传名称
    String originalFilename = uploadFile.getOriginalFilename();
//        把文件转移到c盘下的upload文件夹中
    ploadFile.transferTo(new File("C:\\upload\\"+originalFilename));
    }

2.8.2 多文件上传

直接用数组来接收

<form action="${pageContext.request.contextPath}/user/quick22" method="post" enctype="multipart/form-data">
//都叫uploadFile(也可以叫不同的名字)
    名称<input type="text" name="username"><br>
    文件<input type="file" name="uploadFile"><br>
    文件<input type="file" name="uploadFile"><br>
    文件<input type="file" name="uploadFile"><br>
    文件<input type="file" name="uploadFile"><br>
    <input type="button" name="button">
</form>

2.编写测试代码

@RequestMapping(value = "/quick21/{name}")
@ResponseBody
public void save22(String username, MultipartFile[] uploadFile) throws Exception {
    System.out.println(username);
    System.out.println(uploadFile);
    for (MultipartFile multipartFile : uploadFile) {
        System.out.println(multipartFile);
        String originalFilename = multipartFile.getOriginalFilename();
        multipartFile.transferTo(new File("C:\\upload"+originalFilename));
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值