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";
}
