SpringBoot接口传参方式

常见GET请求和POST请求的区别

1.get请求无消息体,只能携带少量数据,且不安全

post请求有消息体,可以携带大量数据,且安全

2.携带数据的方式:

get请求将数据放在url地址中

post请求将数据放在消息体body中

传参方式

get方式---params

传参格式:?号传参,在地址栏上加参数


http://host:port/path?参数名=参数值

问题一、参数带有斜杠

方法1:修改一下启动类,加一个系统参数,重写WebMvcConfigurerAdapter的configurePathMatch方法

@SpringBootApplication
public class ApplicationextendsWebMvcConfigurerAdapter {

    publicstaticvoidmain(String[] args)throws Exception {
        System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
        SpringApplication.run(Application.class, args);
    }

    @Override
    publicvoidconfigurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelperurlPathHelper=newUrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

参考:Encoded slash (%2F) with Spring RequestMapping path param gives HTTP 400

方法2:

传参方式由URL变量改为Request参数。

post方式---body常见的Content-Type

application/json

application/json是POST请求以JSON的格式向服务请求发起请求或者请求返回JSON格式的响应内容,服务端接受到数据后对JSON进行解析拿到所需要的参数。

默认的数据格式是json格式: {"name": "Michael"}

application/x-www-form-urlencoded

application/x-www-form-urlencoded主要用于表单形式的POST请求中,如普通的表单提交,或者js发包,默认都是通过这种方式。

multipart/form-data

multipart/form-data是使用POST请求上传文件,如果上传照片,文件等,由于很多情况下都会有批量上传,为了区分不同的数据,multipart/form-data的类型有boundary参数进行分割,对上传文件请求抓包。

Content-Typeapplication/x-www-form-urlencoded或者 multipart/form-data时,默认的数格式是a=123&b=123&c=123
用get提交,和post提交是一样的,数据格式都是这样,get和post的区别是,get显示地址栏中,post提交是不显示的,相对于get来说,post这种提交方式更加安全

地址栏传参

直接通过/在地址上拼接参数值,这种方式不需要在地址栏上写参数名,后端只需要知道他在地址的哪个位置传的参数就可以拿到值


http://host:port/path/参数值

接收参数

@PathVariable

作用在形参列表上,接受参数类型:地址栏传参


@RequestMapping(value="/addUser/{username}/{password}")
public void addUser(@PathVariable String username, 
                        @PathVariable String password) {
    System.out.println("username is:"+username);
    System.out.println("password is:"+password);
}

此时测试访问路径: http://127.0.0.1:8883/addUser4/xiadewang/123456,自动将URL中模板变量{username}和{password}绑定到通过@PathVariable注解的同名参数上

注意这里的参数个数一定要保持相同,否则会报404的错误。

@RequestParam

作用在形参列表上,接受参数类型:

params

body的Content-Type为application/x-www-form-urlencoded或者multipart/form-data


@RequestMapping(value="/addUser")
public void addUser(@RequestParam("username") String username,
                        @RequestParam("password") String password) {
    System.out.println("username is:"+username);
    System.out.println("password is:"+password);
}

问题一、设置参数非必填

当@RequestParam(required=false) int XXX 取参数的时候,当参数没有的时候Spring默认赋值为空。而此时使用基本类型int,所以报错,建议使用包装类 Integer。

    @RequestMapping(value = {"/findGroupByGroupName/{batchNo}/{groupSex}"}, method = RequestMethod.GET)
    @ApiOperation(value = "模糊搜索查询分组情况是否成功", notes = "输入分组的批次,分组的性别,分组的部分名称", tags = {"查询"})
    public ResponseResult findGroupByGroupName(
            @ApiParam(name = "batchNo", value = "批次", required = true) @PathVariable String batchNo,
            @ApiParam(name = "groupSex", value = "性别", required = true) @PathVariable String groupSex,
            @ApiParam(name = "groupName", value = "名称") @RequestParam(required = false) String groupName) {
        return null;
    }

@RequestBody

作用在形参列表上,接受参数类型:

body的Content-Type为application/json、application/xml


@RequestMapping(value="/addUser")
public void addUser(@RequestBody User user) {
    System.out.println("username is:"+user.getUsername());
    System.out.println("password is:"+user.getPassword());
}

HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中。

常用的方法和操作:

1.获得客户端信息

getRequestURL--返回客户端发出请求时的完整URL。

getRequestURI--返回请求行中的资源名部分,去掉主机名的部分。

getRemoteAddr--返回发出请求的客户机的IP地址

getRemoteHost--返回发出请求的客户机的完整主机名

getRemotePort--返回客户机所使用的端口号

getLocalAddr--返回WEB服务器的IP地址。

getLocalName--返回WEB服务器的主机名

getMethod--返回客户端请求方式,如GET,POST

2.获得请求头

getHead(name)

getHeaders(String name)

getHeaderNames

3.获得请求参数(客户端提交的数据)

getParameter(name)--获得客户端传送给服务器的参数值

getParameterValues(String name)

getParameterNames

getParameterMap


@RequestMapping("/addUser")
public String addUser(HttpServletRequest request) {
    String username=request.getParameter("username");
    String password=request.getParameter("password");

    return "success";
}

返回参数

@ResponseBody

用于后台返回数据,将java对象转为json格式的数据。

返回结果不会被解析为跳转路径,会直接返回json数据。

作用在方法上、类上。


@ResponseBody
@RequestMapping("/getUser")
public User getUser(@RequestParam("username") String username) {
    User user = userService.getUser(name);
    return user;
}

HttpServletResponse

HttpServletResponse则是对服务器的响应对象。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。

常用的方法

addCookie(Cookie cookie) --向客户端写入Cookie

addHeader(java.lang.String name, java.lang.String value) --写入给定的响应头

encodeURL(java.lang.Stringurl) --默认cookie中包含Session ID,如果客户端不支持 Cookie,就在参数 url 中加入 Session ID 信息,可以解决用户禁用cookie的问题。

setStatus(intsc) --设置响应的状态码。

日期时间格式化

@JsonFormat

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")

将后端返回给前端的日期时间进行格式化

pattern为转换后的格式,timezone为日期时间的时区

提示:

@JsonFormat注解可以在属性的上方,同样可以在属性对应的get方法上,两种方式没有区别;

在POST请求一般用@RequestBody接收JSON对象,使用 @JsonFormat注解对日期时间类型数据进行格式化,它既可以对出参进行格式化,也可以对入参进行格式化。

@DateTimeFormat

@DateTimeFormat(pattern ="yyyy-MM-dd HH:mm:ss")

将前端传给后端的日期时间进行格式化

pattern为转换后的格式

提示:

在GET请求或者Content-Type 为 application/x-www-form-urlencoded的请求,参数都是拼接在URL后面的,则需要使用@DateTimeFormat对入参进行格式化,放到@RequestBody修饰的对象里面是无效的。

全局配置

spring:
  # Content-Type 为 application/json
  # @JsonFormat(优先级高) 或 spring.jackson.date-format
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  # Content-Type 为 application/x-www-form-urlencoded(普通表单上传)
  # spring.mvc.date-format(优先级高) 或 @DatetimeFormat
  mvc:
    date-format: yyyy-MM-dd HH:mm:ss

@JsonFormat格式化LocalDateTime、LocalDate、LocalTime失败

出现问题的版本

在使用Spring Boot 2.0.0 时,直接在字段上加上@JsonFormat 注解就可以完成数据的绑定。

在使用Spring Boot 1.5.8时,只在字段上加上@JsonFormat 注解,在数据绑定时无法将Date类型的数据自动转化为字符串类型的数据。

解决:

将SpringBoot版本升级为2.0.0及以上。

如果不升级SpringBoot版本,可以按照下面的方式解决问题。

不升级SpringBoot版本,添加Jackson对Java Time的支持后,就能解决这个问题。

1、pom.xml新增

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

2、增加配置类JacksonConfig

方法一:只注册JavaTimeModule,字段必须有@JsonFormat注解


@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper serializingObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.findAndRegisterModules();
        return objectMapper;
    }
}

方法二:自动扫描新添加的模块,字段无@JsonFormat注解时,默认yyyy-MM-dd HH:mm:ss


@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper serializingObjectMapper() {
      ObjectMapper objectMapper = new ObjectMapper();
      objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
      objectMapper.registerModule(new JavaTimeModule());
      return objectMapper;
    }
}

或者全局配置


@Configuration
public class JacksonConfig {

    /** 默认日期时间格式 */
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /** 默认日期格式 */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    /** 默认时间格式 */
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    @Bean
    public ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addSerializer(LocalDate.class,new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addSerializer(LocalTime.class,new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDate.class,new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addDeserializer(LocalTime.class,new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        objectMapper.registerModule(javaTimeModule).registerModule(new ParameterNamesModule());
        return objectMapper;
    }
}

设置字段为NULL不返回或者不返回某个字段

1、@JsonInclude(value= JsonInclude.Include.NON_NULL)为NULL不返回
返回的字段属性为null 就不会展示给前端。可以放在java 实体类上,也可以放在字段上。

2、@JSONField(serialize = false) 不返回
放在java 实体类字段上。不管这个字段有没有值都不返回给前端。

问题:返回给前端的字段的大写变成小写(一个小写字母接一个大写字母)

例如 cId

原因是:使用了lombok(生成setCId方法),SpringMvc默认使用jackson解析json,而jackson又依赖于实体类的get/set方法。
处理方式:

1.去掉@Data,手写get/set方法(手写使用setcId)

2.使用别名@JsonProperty("cId") 

3.在使用lombok的时候,不使用一个小写字母接一个大写字母的属性命名

问题:接口调用时返回Content type 'text/plain;charset=UTF-8' not supported

添加 consumes = "application/json"

@RequestMapping(value = "/user", method = RequestMethod.POST, consumes = "application/json")
String getUserId(@RequestBody User user);

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值