【SpringMVC基础学习02】SpringMVC的请求和响应

文章目录

    • 1 SpringMVC的响应response
      • 1.1 页面跳转
      • 1.2 回写数据
    • 2 SpringMVC的请求Request
      • 2.1 获得request参数
          • 2.1.1 基本类型参数
          • 2.1.2 POJO类型参数
          • 2.1.3 数组类型参数
          • 2.1.4 集合类型参数
      • 2.2 获取request时的细节
          • 2.2.1 开启静态资源访问
          • 2.2.2 配置全局乱码过滤器
          • 2.2.3 参数绑定注解@RequestParam
          • 2.2.4 获取Restful风格的参数@PathVariable
          • 2.2.5 自定义类型转换器
          • 2.2.6 获得Servlet相关API
          • 2.2.7 获得请求头信息
      • 2.3 文件上传
        • 2.3.1 文件上传三要素
        • 2.3.2 文件上传原理
        • 2.3.3 单文件上传并解析
        • 2.3.4 多文件上传并解析

1 SpringMVC的响应response

SpringMVC的数据响应方式包括页面跳转回写数据

1.1 页面跳转

  • 直接返回字符串
    【SpringMVC基础学习02】SpringMVC的请求和响应_第1张图片

    以字符串形式返回跳转的页面

    public class QuickController {
        @RequestMapping(value = "/quick")
        public String quickMethod1(){
            System.out.println("quickMethod running.....");
            return "success.jsp"; //资源相对地址
        }
    }
    

    在Controller方法的形参上可以直接使用原生的HttpServeltRequest对象,用原始方式往域中存数据。MVC框架会自动注入形参。

    @RequestMapping(value="/quick2")
    public String save2(HttpServletRequest request){
        request.setAttribute("username","wzj");
        return "success.jsp";
    }
    

    只通过model存数据,视图以字符串形式返回,形参同样通过框架注入(不常用)

    @RequestMapping(value="/quick3")
    public String save3(Model model){
        model.addAttribute("username","zyk");
        return "success.jsp";
    }
    
  • 通过ModelAndView对象返回

    在Controller中创建一个ModelAndView对象,并且设置视图名称(映射到页面)

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

    在Controller中方法形参上直接声明ModelAndView。无需在方法中自己创建,MVC框架会自动注入。在方法中直接使用该对象设置视图,同样可以跳转页面

    @RequestMapping(value="/quick5")
    public ModelAndView save5(ModelAndView modelAndView){
        modelAndView.addObject("username","itheima");
        modelAndView.setViewName("success");
        return modelAndView;
    }
    

1.2 回写数据

web基础中,服务器如果想直接写字符串作为响应体返回,使用response.getWriter().print(“hello world”)

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

  • 直接回写字符串

    /**
     * 为了Servlet API解耦合,一般不用Servlet相关类
     * 所以多用quick7的方式
     */
    @RequestMapping(value="/quick6")
    public void save6(HttpServletResponse response) throws IOException {
        response.getWriter().print("hello 回写字符");
    }
    
    @RequestMapping(value="/quick7")
    @ResponseBody  //告知SpringMVC框架 不进行视图跳转 直接进行数据响应
    public String save7() throws IOException {
        return "hello quick7";
    }
    

    一般直接返回字符串的情况,多见于回写json格式的字符串

    @RequestMapping(value="/quick8")
    @ResponseBody
    public String save8() throws IOException {
        return "{\"username\":\"zhangsan\",\"age\":18}";
    }
    

    更进一步,手动拼接json格式字符串的方式很麻烦,开发中往往要将复杂的java对象转换成json格式的字符串。我们可以通过ObjectMapper把类转换json格式字符串,回写字符串

    @RequestMapping(value="/quick9")
    @ResponseBody
    public String save9() throws IOException {
        User user = new User();
        user.setUsername("lisi");
        user.setAge(30);
        
        //使用json的转换工具将对象转换成json格式字符串在返回
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(user);
        return json;
    }
    
  • 返回对象或集合

    • springMVC封装起了【对象–json字符串】的转换,使我们可以直接回写对象或集合。

      配置spring-mvc.xml,配置【处理器适配器】,告诉他我需要用json转换工具进行转换。RequestMappingHandlerAdapter中有setMessageConverters方法,可以指定一系列消息转换器。因此在spring-mvc.xml中进行如下配置:

      
      <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
              <property name="messageConverters">
                  <list>
                      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
                  list>
              property>
          bean>
      
      @RequestMapping(value="/quick10")
      @ResponseBody
      //期望SpringMVC自动将User转换成json格式的字符串
      public User save10() throws IOException {
          User user = new User();
          user.setUsername("lisi2");
          user.setAge(32);
          return user;
      }
      

      在 SpringMVC 的各个组件中,处理器映射器RequestMappingHandlerMapping处理器适配器RequestMappingHandlerAdapter视图解析器称为 SpringMVC 的三大组件。

      使用mvc注解驱动,可以自动加载处理器映射器、处理器适配器,免去手动配置。同时默认底层就会集成jackson进行对象或集合的json格式字符串的转换。

      
      
      
      
      
      
      
      
      
      
      <mvc:annotation-driven />
      



2 SpringMVC的请求Request

2.1 获得request参数

客户端请求参数的格式是:name=value&name=value……

服务器端要获得请求的参数,有时还需要进行数据的封装和传递。

SpringMVC可以接收如下类型的参数

2.1.1 基本类型参数

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型转换;自动的类型转换是指从String向其他类型的转换

请求格式:http://localhost:8080/xxx/quick11?username=zhangsan&age=12

@RequestMapping(value="/quick11")
@ResponseBody
public void save11(String username,int age) throws IOException {
    System.out.println(username);
    System.out.println(age);
}

2.1.2 POJO类型参数

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

@RequestMapping(value="/quick12")
@ResponseBody
public void save12(User user) throws IOException {
    System.out.println(user);
}
2.1.3 数组类型参数

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

请求格式:``http://localhost:8080/xxx/quick13?strs=111&strs=222&strs=mcq`

@RequestMapping(value="/quick13")
@ResponseBody
public void save13(String[] strs) throws IOException {
    System.out.println(Arrays.asList(strs));
}
2.1.4 集合类型参数
  • 获得集合参数时,要将集合参数包装到一个POJO中才可以,这里使用VO类来封装集合数据

    package com.itheima.domain;
    import java.util.List;
    
    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 +
                    '}';
        }
    }
    
    

    form.jsp

    <%--在这里去请求quick14--%>
    <form action="${pageContext.request.contextPath}/user/quick14" method="post">
        <%--表明是第一个User对象的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" value="提交">
    form>
    

    Controller中

    请求格式:直接访问form.jsp,填写表单提交

    @RequestMapping(value="/quick14")
    @ResponseBody
    public void save14(VO vo) throws IOException {
        System.out.println(vo);
    }
    

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

    ajax.jsp

    <%--这里使用ajax,需要自己导入一个jquery--%>
    <script src="${pageContext.request.contextPath}/js/jquery.js">script>
    <script>
        var userList = new Array();
        userList.push({username:"zhangsan",age:18});
        userList.push({username:"lisi",age:28});
    
        //ajax发送数据
        $.ajax({
            type:"POST",
            url:"${pageContext.request.contextPath}/quick15",
            data:JSON.stringify(userList),
            contentType:"application/json;charset=utf-8"
        });
    
    script>
    

    Controller中

    请求格式:直接访问ajax.jsp,调用页面里的js

    @RequestMapping(value="/quick15")
    @ResponseBody
    //把集合封装在请求体当中
    public void save15(@RequestBody List<User> userList) throws IOException {
        System.out.println(userList);
    }
    

2.2 获取request时的细节

2.2.1 开启静态资源访问

当有静态资源需要加载时,比如jquery文件,通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源:

  • 在spring-mvc.xml配置文件中指定放行的资源

  • 使用标签

<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/img/**" location="/img/" />


<mvc:default-servlet-handler />
2.2.2 配置全局乱码过滤器

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


<filter>
    <filter-name>CharacterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    <init-param>
        <param-name>encodingparam-name>
        <param-value>UTF-8param-value>
    init-param>
filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>
2.2.3 参数绑定注解@RequestParam

当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解,与前端页面显示的绑定。其参数如下:

  • value
  • required
  • defaultValue

form.jsp中声明name

<form action="${pageContext.request.contextPath}/quick16" method="post">
    <input type="text" name="name"><br>
    <input type="submit" value="提交"><br>
form>

@RequestMapping(value="/quick16")
@ResponseBody
public void save16(@RequestParam(value="name",required = false,defaultValue = "itcast") String username) throws IOException {
    System.out.println(username);
}

2.2.4 获取Restful风格的参数@PathVariable

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

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

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

/user/1 GET : 得到 id = 1 的 user

/user/1 DELETE: 删除 id = 1 的 user

/user/1 PUT: 更新 id = 1 的 user

/user POST: 新增 user

上述url地址/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。地址/user/1可以写成/user/{id},占位符{id}对应的就是1的值。使用@PathVariable注解标记的变量,会与占位符匹配,以解析地址中的参数。

请求格式:http://localhost:8080/xxx/quick17/machunqi

@RequestMapping(value="/quick17/{name}")
@ResponseBody
public void save17(@PathVariable(value="name") String username) throws IOException {
    System.out.println(username);
}

2.2.5 自定义类型转换器

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

  1. 定义转换器converter.DataConverter

    public class DateConverter implements Converter<String, Date> {
        public Date convert(String dateStr) {
            //将日期字符串转换成日期对象 返回
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = format.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
    
  2. springmvc.xml中声明转换器

    
        <bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="converter.DataConverter">bean>
                list>
            property>
        bean>
    
    
  3. 在注解驱动中引用自定义的转换器

请求格式:http://localhost:8080/xxx/quick18/?date=2020-09-10

@RequestMapping(value="/quick18")
@ResponseBody
public void save18(Date date) throws IOException {
    System.out.println(date);
}

2.2.6 获得Servlet相关API

SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象有:HttpServletRequest、HttpServletResponse、HttpSession

@RequestMapping(value="/quick19")
@ResponseBody
public void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
}

2.2.7 获得请求头信息

@RequestHeader注解可以获得请求头信息,相当于request.getHeader(name)。其参数如下:

  • value:请求头的名称

  • required:是否必须携带此请求头

@RequestMapping(value="/quick20")
@ResponseBody
public void save20(@RequestHeader(value = "User-Agent",required = false) String user_agent) throws IOException {
    System.out.println(user_agent);
}

@CookieValue可以获得指定Cookie的值。其参数如下:

@CookieValue注解的属性如下:

  • value:指定cookie的名称

  • required:是否必须携带此cookie

@RequestMapping(value="/quick21")
@ResponseBody
public void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {
    System.out.println(jsessionId);
}


2.3 文件上传

2.3.1 文件上传三要素

文件上传也属于客户端请求,服务端接收。文件上传客户端表单需要满足:

  • 表单项type=“file”

  • 表单的提交方式是post

  • 表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”

<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/>
        <input type="submit" value="提交">
form>

2.3.2 文件上传原理

【SpringMVC基础学习02】SpringMVC的请求和响应_第2张图片

2.3.3 单文件上传并解析

  1. 添加依赖

    <dependency>
        <groupId>commons-fileuploadgroupId>
        <artifactId>commons-fileuploadartifactId>
        <version>1.3.1version>
    dependency>
    <dependency>
        <groupId>commons-iogroupId>
        <artifactId>commons-ioartifactId>
        <version>2.3version>
    dependency>
    
  2. 配置文件上传解析器

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

    客户端上传的文件会被springmvc封装成MultipartFile类型的对象,要注意对象名与页面中file标签的名称对应

    //获取上传的单个文件
    @RequestMapping(value="/quick22")
    @ResponseBody
    public void save22(String username, MultipartFile uploadFile) throws IOException {
        System.out.println(username);
        System.out.println(uploadFile);
    
        //获得上传文件的名称并保存文件
        String originalFilename = uploadFile.getOriginalFilename();
        uploadFile.transferTo(new File("D:\\files\\javaWorks\\Spring\\spring_mvc_webapp"+originalFilename));
    }
    

2.3.4 多文件上传并解析

多文件上传,只需要将页面修改为多个文件上传项,客户端使用MultipartFile数组接收

名称
文件1
文件2
@RequestMapping(value="/quick23")
@ResponseBody
public void save23(String username, MultipartFile[] uploadFile) throws IOException {
    System.out.println(username);
    for (MultipartFile multipartFile : uploadFile) {
        String originalFilename = multipartFile.getOriginalFilename();
        multipartFile.transferTo(new File("C:\\upload\\"+originalFilename));
    }
}

你可能感兴趣的:(java,spring)