SpringMVC请求参数

SpringMVC请求参数

一、概述

二、请求方式

RequestMapping可以由于所以请求,可以用在类上面,这些它下面的方法都要进行拼接路径,当然GetMapping也可以用在类上面,这样就指定了下面所有方法的请求方式了。

这是RequestMapping源码:

java 复制代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";

    @AliasFor("path")
    String[] value() default {};

    @AliasFor("value")
    String[] path() default {};

    RequestMethod[] method() default {};

    String[] params() default {};

    String[] headers() default {};

    String[] consumes() default {};

    String[] produces() default {};
}

path与value等价, RequestMethod是枚举类型:

java 复制代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.web.bind.annotation;

public enum RequestMethod {
    GET,
    HEAD,
    POST,
    PUT,
    PATCH,
    DELETE,
    OPTIONS,
    TRACE;

    private RequestMethod() {
    }
}
java 复制代码
package com.itheima.controller;

import com.itheima.service.QuickService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

//定义成为Bean
@Controller
@RequestMapping("/aaa")
public class QuickController2 {
//    注入配置好的Service
//    @Autowired
//    private QuickService quickService;
    //这是映射地址
//    @RequestMapping(value = {"/quick","/quickxxx","/quickyyy"},method = RequestMethod.GET)
    @GetMapping(value = {"/quick","/quickxxx","/quickyyy"})
    public String quick()
    {
        System.out.println("quick is running");
        return "/index.jsp";
    }
}

三、数据传递

3.1基本传输形式

java 复制代码
package com.itheima.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.pojo.User;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

@Controller
public class ParamController2 {
//    正常访问,客户端与服务端参数匹配时
//http://localhost/param1?username=zhangsan&age=18
@RequestMapping("/param1")
public String param1(String username,int age){
    System.out.println(username+"===="+age);
    return "/index.jsp";
}

//    客户端与服务端名字不匹配是使用@RequestParam注解且指定对应的客户端参数名
    //http://localhost/param1?username=zhangsan&age=18
    @RequestMapping("/param2")
    public String param2(@RequestParam("username") String name,int age){
        System.out.println(name+"===="+age);
        return "/index.jsp";
    }
    //多个值时
    //    使用数组进行接收
    //http://localhost/param3?hobby=zq&hobby=pq&hobby=tq
    @RequestMapping("/param3")
    public String param3(String hobby[]){
        for (String s : hobby){
            System.out.println(s);
            }
        return "/index.jsp";
        }
    //使用List进行接收,由于SpingMVC会把List当成一个对象,创建对象进行封装,然后List是一个接口无法创建对象,所以我们要使用@RequestParam来告诉SpringMVC我们只想简单的封装
    @RequestMapping("/param4")
    public String param4(@RequestParam List<String>hobby){
        for (String s : hobby){
            System.out.println(s);
        }
        return "/index.jsp";
    }
    //    使用Map进行封装也是要加@RequestParam以表明这与客户端的参数对应,因为Map无法在名字上与多个变量进行对应
//    http://localhost/param5?username=zhangsan&age=18
    @RequestMapping("/param5")
    public String param5(@RequestParam Map<String,String>map){
        map.forEach((k,v)->{
            System.out.println(k+"=="+v);
        });
        return "/index.jsp";
    }
}

map传输是这样的,对应参数对应要求不高:

然后下面再补充几个属性:required是表示是否必须传输,默认是false的,然后还可以通过defaultValue指定默认值

java 复制代码
@RequestMapping("/param1")
public String param1(@RequestParam(required = true,defaultValue = "mm") String username,Integer age){
    System.out.println(username+"===="+age);
    return "/index.jsp";
}

同时int是基本类型不能为空,为空的话会报错:

改为Integer即可。

3.2封装为实体类传输

java 复制代码
package com.itheima.pojo;

import java.util.Arrays;
import java.util.Date;

public class User {

    private String username;
    private Integer age;
    private String[] hobbies;
    private Date birthday;
    private Address address;

    public String getUsername() {
        return username;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String[] getHobbies() {
        return hobbies;
    }

    public void setHobbies(String[] hobbies) {
        this.hobbies = hobbies;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                ", hobbies=" + Arrays.toString(hobbies) +
                ", birthday=" + birthday +
                ", address=" + address +
                '}';
    }
}
java 复制代码
package com.itheima.pojo;

public class Address {

    private String city;
    private String area;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    @Override
    public String toString() {
        return "Address{" +
                "city='" + city + '\'' +
                ", area='" + area + '\'' +
                '}';
    }
}
java 复制代码
//    封装到实体当中,SpringMVC框架调用底层的set方法来进行反射
//    //http://localhost/param6?username=zhangsan&age=18&hobbies=zq&hobbies=pq&birthday=2018/11/11&address.city=tj&address.area=bh
@RequestMapping("/param6")
public String param6(User user){
    System.out.println(user);
    return "/index.jsp";

要是对象里面有对象像address一样,使用"实体类.属性"形式传输。

3.3 使用@RequestBody注解接收客户端传过来的JSON格式的字符串数据(封装为请求体)

3.3.1直接保留字符串形式
java 复制代码
@PostMapping("/param8")
    public String param8(@RequestBody String body){
        System.out.println(body);
        return "/index.jsp";
    }


当然我们也可以将客户端传递过来的JSON字符串转化为对象:

3.3.2将客户端传递过来的JSON字符串转化为对象
java 复制代码
 //    将客户端传递过来的JSON数据的请求体转化为为一个对象
    @PostMapping("/param9")
    public String param9(@RequestBody String body) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = objectMapper.readValue(body, User.class);
        System.out.println(user);
        return "/index.jsp";
    }

那如果每次都要写" ObjectMapper objectMapper = new ObjectMapper();User user = objectMapper.readValue(body, User.class);"势必会造成高耦合,所以我们直接配置RequestMappingHandlerAdapter的MappingJackson2HttpMessageConverter是实现JSON数据的请求体自动转化为为一个对象:

java 复制代码
//    配置RequestMappingHandlerAdapter的MappingJackson2HttpMessageConverter是实现JSON数据的请求体自动转化为为一个对象
    @PostMapping("/param10")
    public String param10(@RequestBody User user){
        System.out.println(user);
        return "/index.jsp";
    }

前面我们也学过配置SpringMVC的那几大组件(在SpringMVC的配置文件中进行配置),如果不配置的话会默认加载,因为我们要使用到一些属性,默认加载的没有,所以我们自己进行配置,RequestMappingHandlerAdapter有这样的属性:

java 复制代码
private List<HttpMessageConverter<?>> messageConverters = new ArrayList(4);

然后配置其中的MappingJackson2HttpMessageConverter即可:

java 复制代码
<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>

这样就可以自动转换了:

四、Restful风格传输数据

Rest(Representational State Transfer)表象化状态转变(表述性状态转变),在 2000 年被提出,基于 HTTP、URL、xml、JSON 等标准和协议,支持轻量级、跨平台、跨语言的架构设计。是 Web 服务的一种新网络应用程序的设计风格和开发方式。


使用Restful风格来进行Get请求:

需要使用@PathVariable注解来将URL中的参数名与代码中的参数名进行映射:

java 复制代码
//    使用Restful风格完成get请求,参数加在后面加占位符,而且前面的必须是名词
    @GetMapping("/user/{id}/{yyy}")
    public String findUserById(@PathVariable("id") String id,@PathVariable("yyy") String xxx){
        System.out.println("id:"+id);
        System.out.println("xxx:"+xxx);
        return "/index.jsp";
    }

五、文件上传

客户端要求:

(如果客户端不选择格式的话默认是EnCoding的格式)

服务端要求:

由于映射器适配器需要文件上传解析器,而该解析器默认未被注册,所以手动注册:

java 复制代码
<!--配置文件上传解析器,注意:id的名字是固定写法-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

而 CommonsMultipartResolver 底层使用的 Apache 的是 Common-fileupload 等工具 API 进行的文件上传,所以还要导入坐标:

java 复制代码
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

来测试一下吧:

java 复制代码
 //    实现文件上传功能
//    前端使用POST请求,且是MultyForm
//    后端使用 MultipartFile接收(与前端同名)
    @PostMapping("/param11")
    public String param11(@RequestBody MultipartFile myfile){
        System.out.println(myfile);
        return "/index.jsp";
    }


可以了。

当然还可以补充CommonsMultipartResolver属性:

java 复制代码
<!--配置文件上传解析器,注意:id的名字是固定写法-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"/><!--文件的编码格式 默认是ISO8859-1-->
    <property name="maxUploadSizePerFile" value="1048576"/><!--上传的每个文件限制的大小 单位字节-->
    <property name="maxUploadSize" value="3145728"/><!--上传文件的总大小-->
    <property name="maxInMemorySize" value="1048576"/><!--上传文件的缓存大小-->
</bean>

文件保存:

java 复制代码
@PostMapping("/param11")
    public String param11(@RequestBody MultipartFile myfile) throws IOException {
        System.out.println(myfile);
//        实现文件的保存
//        获取输入流
        InputStream inputStream = myfile.getInputStream();
//        定义输出流
        OutputStream outputStream = new FileOutputStream("C:\\Users\\PFR\\Desktop\\MM\\"+myfile.getOriginalFilename());
//        执行文件复制
        IOUtils.copy(inputStream,outputStream);

//        关闭流
        inputStream.close();
        outputStream.close();
        return "/index.jsp";
    }

文件复制实际上是我们之前导入的CommonsMultipartResolver带的org.apache.commons.io包:

六、获取请求头和Cookie的信息

6.1获取请求头

java 复制代码
//    获取请求头的信息
//    获取单个请求头
    @GetMapping("/param12")
    public String param12(@RequestHeader("accept-encoding") String requestHeader){
        System.out.println(requestHeader);
        return "/index.jsp";
    }

获取所有请求头的信息使用Map接收:

java 复制代码
//    获取所有请求头(使用Map容器进行接收)
@GetMapping("/param13")
public String param13(@RequestHeader Map<String,String>requestHeader){
    requestHeader.forEach((k,v)->{
        System.out.println(k+"=>"+v);
    });
    return "/index.jsp";
}

6.2获取Cookie信息

java 复制代码
//  获取Cookie的信息
    @GetMapping("/param14")
    public String param14(@CookieValue(value = "JSESSIONID",defaultValue = "") String jsessionid){
        System.out.println(jsessionid);
        return "/index.jsp";
    }

七、直接获取Request和session域中的数据

java 复制代码
//    直接获取Request和session域中的数据
        @GetMapping("/request1")
        public String Request1(HttpServletRequest httpServletRequest){
        //    向 Request域中存储数据
            httpServletRequest.setAttribute("name","mm");
            return "/request2";
        }
        //    接收数据
        @GetMapping("/request2")
        public String Request2(@RequestAttribute("name") String name){
            //    向 Request域中存储数据
            System.out.println(name);
            return "/index.jsp";
    }


当然@SessionAttribute也是同理。

八、在SpringMVC框架获取JavaWeb的常用对象------Resquest和Response

java 复制代码
//    在SpringMVC框架获取JavaWeb的常用对象------Resquest和Response
    @GetMapping("/param15")
    public String param15(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse){
        System.out.println(httpServletRequest);
        System.out.println(httpServletResponse);
        return "/index.jsp";
    }
相关推荐
ID_180079054732 小时前
小红书笔记评论 API,Python 调用示例与完整 JSON 返回参考
java·开发语言
lifewange2 小时前
java连接Mysql数据库
java·数据库·mysql
忆想不到的晖2 小时前
Codex 探索:别急着调 Prompt,先把工作流收住
后端·agent·ai编程
云原生指北3 小时前
命令行四件套:fd-rg-fzf-bat
java·大数据·elasticsearch
weixin_408099673 小时前
【实战对比】在线 OCR 识别 vs OCR API 接口:从个人工具到系统集成该怎么选?
图像处理·人工智能·后端·ocr·api·图片文字识别·文字识别ocr
人间打气筒(Ada)3 小时前
go实战案例:如何通过 Service Meh 实现熔断和限流
java·开发语言·golang·web·istio·service mesh·熔断限流
Victor3564 小时前
MongoDB(73)如何设置用户权限?
后端
Victor3564 小时前
MongoDB(74)什么是数据库级别和集合级别的访问控制?
后端
主宰者4 小时前
C# CommunityToolkit.Mvvm全局事件
java·前端·c#