Spring Boot 跨域访问和 配置 Jackson

179 阅读3分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

Spring Boot 跨域访问和 配置 Jackson

本节中,您将学习如何在 Spring Boot 中配置跨域访问。首先,我们了解下什么是跨域访问?

您将学习如何在 Spring Boot 中配置 Jackson。什么是 Jackson ? 有什么作用?

出于安全的考虑,浏览器会禁止 Ajax 访问不同域的地址,在现如今微服务横行的年代,跨域访问是非常常见的。W3C 的 CORS (Cross-origin-resource-sharing) 规范中也已经允许跨域访问, 并被主流浏览器所支持,它们包括:

  • Chrome 3+;
  • Firefox 3.5+;
  • Opera 12+;
  • Safari 4+;
  • IE 8+;

如何在 Spring Boot 中配置跨域访问呢?

Spring Boot 提供了对 CORS 的支持,您可以实现 addCorsMappings 接口来添加规则来允许跨域访问:

 package site.exception.config;
 ​
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 ​
 /**
  * @date 2019/2/13
  * @time 下午8:36
  * @discription
  **/
 public class CORSConfig extends WebMvcConfigurerAdapter {
 ​
     @Override
     public void addCorsMappings(CorsRegistry registry) {
         // 允许所有跨域访问
         registry.addMapping("/**");
     }
 ​
 }

/** 允许所有域名都能够跨域访问,下面看看更为精细的控制:

 package site.exception.config;
 ​
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 ​
 /**
  * @date 2019/2/13
  * @time 下午8:36
  * @discription
  **/
 public class CORSConfig extends WebMvcConfigurerAdapter {
 ​
     @Override
     public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/api/**")
                 .allowedOrigins("http://www.exception.site")
                 .allowedMethods("POST", "GET");
     }
 ​
 }

通过上面的配置,只允许来自 www.exception.site 的跨域访问,并且限定只能对 /api 下的所有接口进行跨域访问,同时只能访问 POSTGET 方法。

跨域访问的原理

跨域访问的原理其实很简单,当发起跨域请求的时候,浏览器会对请求域返回的 HTTP 头进行检查,如果 Access-Control-Allow-Origin 包含了自身域,则表示允许访问,否者报错。这也正是上述代码中 allowedOrigins() 方法的作用。

Jackson 是 Spring Boot 内置的 Json 解析框架,用来完成出入参的序列化和反序列化。通常,我们会在 Controller 类中方法上,加上 @RequestBody 或者 @ResponseBody 注解,Spring Boot 会自动对出入参做 Json 解析与转换工作。

注意:@RequestBody用于将入参 Json 转换成对象,而 @ResponseBody 用于将对象转换成 Json 返回。

已经内置,为何还需要配置?

内置的 Jackson 无法满足生产所需,比如说对自定义日期格式,亦或者我们想适配 Java 8 新加入的 LocalDateLocalDateTime 等。

下面以自定义日期格式转换为例,新建一个示例项目,定义一个 /user 接口:

 package site.exception.springbootjackson.controller;
 ​
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 import site.exception.springbootjackson.entity.User;
 ​
 /**
  * @date 2019/2/16
  * @time 21:03
  * @discription
  **/
 @RestController
 public class UserController {
 ​
     /**
      * 定义一个创建用户的接口
      * @param user
      * @return
      */
     @PostMapping("/user")
     public User createUser(@RequestBody User user) {
         System.out.println(user.getCreateTime().toString());
         // 将 user 再以 Json 的形式返回
         return user;
     }
 }

User.java:

 package site.exception.springbootjackson.entity;
 ​
 import java.io.Serializable;
 import java.util.Date;
 ​
 /**
  * @date 2019/2/16
  * @time 21:00
  * @discription
  **/
 public class User implements Serializable {
     /**
      * 用户名
      */
     private String username;
     /**
      * 密码
      */
     private String password;
     /**
      * 创建时间
      */
     private Date createTime;
 ​
     public String getUsername() {
         return username;
     }
 ​
     public void setUsername(String username) {
         this.username = username;
     }
 ​
     public String getPassword() {
         return password;
     }
 ​
     public void setPassword(String password) {
         this.password = password;
     }
 ​
     public Date getCreateTime() {
         return createTime;
     }
 ​
     public void setCreateTime(Date createTime) {
         this.createTime = createTime;
     }
 }

上面这个接口我们直接使用的 @RestController, 它会将此 Controller 中的方法均以 Json 的格式进行返回。完成这一切以后,启动项目,并通过 Postman 访问该接口,测试一下 Json 格式提交能否进行正常转换:

很不幸,报错了!接下来,我们需要自定义格式转换。

配置 Jackson

定义一个 JacksonConfig 配置类:

 package site.exception.springbootjackson.config;
 ​
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 ​
 import java.text.SimpleDateFormat;
 ​
 /**
  * @date 2019/2/17
  * @time 19:32
  * @discription
  **/
 @Configuration
 public class JacksonConfig {
 ​
     @Bean
     public ObjectMapper objectMapper() {
         ObjectMapper objectMapper = new ObjectMapper();
         // 自定义日期转换格式
         objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
         return objectMapper;
     }
 }

重新启动项目,再次对该接口访问:

img

可以看到正常返回 Json 对象,并且控制台也正确打印出了 createTime:

img

到此,在 Spring Boot 中配置 Jackson,并对日期自定义格式转换就完成了!