Spring boot (6): spring boot uses CROS to solve cross domain problems

Cross domain issues have been mentioned before. If you don't understand, please refer to my previous article. This chapter mainly explains the support of spring boot cros.

It is mainly described in the form of official documents.

SpringBoot CROS reference: http://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/htmlsingle/#boot-features-cors

Spring CROS reference: http://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/htmlsingle/#cors

1, Code preparation

First of all, Restful controller is supported. Here, database is not used. It's simple. UserController.class

package cn.saytime.web;

import cn.saytime.bean.JsonResult;
import cn.saytime.bean.User;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zh
 * @ClassName cn.saytime.web.UserController
 * @Description
 */
@RestController
public class UserController {

    // Create a thread safe Map
    static Map<Integer, User> users = Collections.synchronizedMap(new HashMap<Integer, User>());

    /**
     * Query users by ID
     * @param id
     * @return
     */
    @RequestMapping(value = "user/{id}", method = RequestMethod.GET)
    public ResponseEntity<JsonResult> getUserById (@PathVariable(value = "id") Integer id){
        JsonResult r = new JsonResult();
        try {
            User user = users.get(id);
            r.setResult(user);
            r.setStatus("ok");
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");
            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * Query user list
     * @return
     */
     @CrossOrigin
    @RequestMapping(value = "users", method = RequestMethod.GET)
    public ResponseEntity<JsonResult> getUserList (){
        JsonResult r = new JsonResult();
        try {
            List<User> userList = new ArrayList<User>(users.values());
            r.setResult(userList);
            r.setStatus("ok");
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");
            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * Add user
     * @param user
     * @return
     */
    @RequestMapping(value = "user", method = RequestMethod.POST)
    public ResponseEntity<JsonResult> add (@RequestBody User user){
        JsonResult r = new JsonResult();
        try {
            users.put(user.getId(), user);
            r.setResult(user.getId());
            r.setStatus("ok");
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");

            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * Delete user by id
     * @param id
     * @return
     */
    @RequestMapping(value = "user/{id}", method = RequestMethod.DELETE)
    public ResponseEntity<JsonResult> delete (@PathVariable(value = "id") Integer id){
        JsonResult r = new JsonResult();
        try {
            users.remove(id);
            r.setResult(id);
            r.setStatus("ok");
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");

            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

    /**
     * Modify user information according to id
     * @param user
     * @return
     */
    @RequestMapping(value = "user/{id}", method = RequestMethod.PUT)
    public ResponseEntity<JsonResult> update (@PathVariable("id") Integer id, @RequestBody User user){
        JsonResult r = new JsonResult();
        try {
            User u = users.get(id);
            u.setUsername(user.getUsername());
            u.setAge(user.getAge());
            users.put(id, u);
            r.setResult(u);
            r.setStatus("ok");
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus("error");

            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }

}

User.class

package cn.saytime.bean;

import java.util.Date;

/**
 * @author zh
 * @ClassName cn.saytime.bean.User
 * @Description
 */
public class User {

    private int id;
    private String username;
    private int age;
    private Date ctm;

    // Getter Setter
}

JsonResult.class

package cn.saytime.bean;

public class JsonResult {

    private String status = null;

    private Object result = null;

    // Getter Setter
}

2, Test for cross domain issues

Let's create a new test.html in the static directory

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/2.1.0/jquery.min.js"></script>
    <script type="text/javascript">
        function crosRequest(){
            $.ajax({
                url:'http://localhost:8080/users',
                type:'get',
                dataType:'json',
                success:function(data){
                    console.log(data);
                }
            });
        }
    </script>
</head>
<body>
    <button onclick="crosRequest()">Request cross domain resources</button>
</body>
</html>
  1. We use the browser preview function of IDEA and click on the small icon of Google http://localhost:63342/springboot-demo/springboot-cros/static/test.html?_ijt=ibtt432ffb9rh0vffqkkug3je8
  2. Start the SpringBoot project, the default is 8080

Instead of using IDEA, find a tomcat to start the test.html page, change the port to other, and then start springboot.

So it is proved that there are cross domain problems.

1, @ CrossOrigin annotation method Controller method CORS configuration

Here we add @ CrossOrigin to the getUserList method of users mapping

@CrossOrigin
    @RequestMapping(value = "users", method = RequestMethod.GET)
    public ResponseEntity<JsonResult> getUserList ()

Then access again using the above method.

Indicates cross domain problem solving. The official document above the default @ CrossOrigin allow all origins and the HTTP methods specified in the @ requestmapping annotation indicates that the default @ CrossOrigin allows all cross domain requests.

You can see from the CrossOrigin source code that the default configuration is:

"Access-Control-Allow-Origin" : "*"
"Access-Control-Allow-Methods" : "GET,POST,PUT,OPTIONS"
"Access-Control-Allow-Credentials" : "true"
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
    /** @deprecated */
    @Deprecated
    String[] DEFAULT_ORIGINS = new String[]{"*"};
    /** @deprecated */
    @Deprecated
    String[] DEFAULT_ALLOWED_HEADERS = new String[]{"*"};
    /** @deprecated */
    @Deprecated
    boolean DEFAULT_ALLOW_CREDENTIALS = true;
    /** @deprecated */
    @Deprecated
    long DEFAULT_MAX_AGE = 1800L;

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

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

    String[] allowedHeaders() default {};

    String[] exposedHeaders() default {};

    RequestMethod[] methods() default {};

    String allowCredentials() default "";

    long maxAge() default -1L;
}

It is also possible to enable CORS for the whole controller. That is, all mappings of the controller support cross domain requests.

@CrossOrigin(origins = "http://domain2.com",
        maxAge = 3600,
        methods = {RequestMethod.GET, RequestMethod.POST})
@RestController
public class UserController

2, Global CORS configuration

Global CORS configuration In addition to fine-grained, annotation-based configuration you'll probably want to define some global CORS configuration as well. This is similar to using filters but can be declared withing Spring MVC and combined with fine-grained @CrossOrigin configuration. By default all origins and GET, HEAD and POST methods are allowed.

package cn.saytime.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @author zh
 * @ClassName cn.saytime.config.CORSConfiguration
 * @Description
 */
@Configuration
public class CORSConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
//              registry.addMapping("/api/**");
                registry.addMapping("/**")
                        .allowedOrigins("http://domain.com", "http://domain2.com")
                        .allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
                        .allowCredentials(false).maxAge(3600);
            }
        };
    }
}

3, Filter based CORS support

@Configuration
public class MyConfiguration {

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(false);
        config.addAllowedOrigin("http://domain.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

                    

Reproduced from: http://blog.csdn.net/saytime

Tags: Spring Java SpringBoot JQuery

Posted on Mon, 04 May 2020 03:46:03 -0700 by hi2you