I created an api domain with Spring Framework. Part 2

Click here for the previous settings

I created an api domain with Spring Framework. Part 1

Prepare your own filter.

It seems that Spring does not have a function to distribute access by subdomain. So, you can solve it by ** adding a special header when accessing a specific subdomain **.

For that, first let's make the filter you made work when subdomain of "api". First, add a Filter to web.xml.

web.xml


  <!--Filters for subdomains-->
  <filter>
		<filter-name>subDomainFilter</filter-name>
		<filter-class>com.TsugaruInfo.config.SubDomainFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>subDomainFilter</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>ERROR</dispatcher>
	</filter-mapping>

com.TsugaruInfo.config.SubDomainFilter Is a unique filter that we will make. This filter is set to accept all URLs.

Implement a filter class

Now let's implement a subdomain filter. Filters can be created by inheriting ** GenericFilterBean **. GenericFilterBean must override ** doFilter **, "Finally, execute FilterChain's doFilter and return the request and response to the controller." It has the property of.

In other words, you can attach the header to this request and return it to the controller. Then it looks like this.

SubDomainFilter.java



public class SubDomainFilter extends GenericFilterBean {
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
			throws IOException, ServletException {
		//TODO auto-generated method stub
		
		//Materialize subdomain wrapper
		SubDomainHttpServletRequestWrapper httpRequest =
				new SubDomainHttpServletRequestWrapper((HttpServletRequest) request);
		
		//Get a subdomain
		String subDomain = getSubDomain(httpRequest);
		
		//If you succeed in getting the api subdomain, run the filter and exit
	if(subDomain != null) {
			httpRequest.addHeader("X-SUBDOMAIN", subDomain);
		}
	else {
		//Other headers when not subdomain access
		httpRequest.addHeader("X-SUBDOMAIN", "topDomain");
	}

	filterChain.doFilter(httpRequest, response);
	}
		
	/**
	 *Header judgment part Judges whether the access is as an api
	 * @param httpRequest
	 * @return
	 */
	private String getSubDomain(HttpServletRequest httpRequest) {
		List<String> subdomains = new ArrayList<String>();
		
		//The subdomain is "api".Returns an api string when starting with localhost
				if(httpRequest.getHeader("host").matches("api.*")) {
					return "api";
				}
				
				return null;
	}
}

"When there is a character" api "in the" host "header of the request, I am trying to edit my own header, X-SUBDOMEIN.

So, there are some classes that are missing. HttpRequest doesn't have the ability to edit headers. So I am making a wrapper class for HttpRequest.

SubDomainHttpServletRequestWrapper.java



/**
 *A subclass with getHeader and addHeader added to subdomain operations
 * @author nozawa
 *
 */
public class SubDomainHttpServletRequestWrapper extends HttpServletRequestWrapper {

	//Header information is copied to this map
	private Map<String, String> headers = new HashMap<String, String>();
	
	public SubDomainHttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
		
		//Get request header
		Enumeration<String> headers_head = request.getHeaderNames();
				
		//Get header name
				while(headers_head.hasMoreElements()){
					String header = headers_head.nextElement();
					Enumeration<String> values = request.getHeaders(header);
		//Set header value
				while(values.hasMoreElements()) { 
					String value = values.nextElement();
					headers.put(header, value);
					}
				}
	}

	
	/**
	 *Header added
	 * @param name
	 * @param value
	 */
	public void addHeader(String name, String value){
		headers.put(name, value);
	}
	
	/**
	 *Get Header
	 */
	public String getHeader(String name) {
		if(headers.containsKey(name)) {
			return headers.get(name);
		}
		
		return ((HttpServletRequest)getRequest()).getHeader(name);
		
	}
}


This wrapper class copies the header information stored as a fixed value of the enumeration to the map of its own class. The controller considers the fields of this class as header information, so it would be nice to be able to edit this map. (Maybe it's a little clunky, please tell me if there is an efficient way)

I will actually access it.

Now let's create a controller for the api and access it!

First, Create two controller methods with the same URL.

APIPictureController.java


@RequestMapping(value="/api/picture", produces="application/json;charset=UTF-8")
@RestController
public class APIPictureController {

	@RequestMapping(value = "/picture_api", method = RequestMethod.GET, headers = "X-SUBDOMAIN=api")
	public String apiStreaming( HttpServletRequest request) {
		request.getHeaderNames();
		return "{\"text\":\"api_Sucessed\"}";
	}
	
	@RequestMapping(value = "/picture_api", method = RequestMethod.GET)
	public String normalStreaming( HttpServletRequest request) {

		request.getHeaderNames();
		return "{\"text\":\"api_notActivate\"}";
	}

These two methods are sorted according to the value of the headers field that exists in the request. Only when X-SUBDOMEIN is api, the api method works.

Let's actually access it.

When accessing localhost

image.png

api. When accessing localhost

image.png

The subdomain allowed us to tally access. ヾ (.> ﹏ <.) No All you have to do is write the function you want to write

reference

I'm ashamed to say that it didn't work so much, so I'm changing it.

Allocate subdomains with @RequestMapping in Spring MVC. http://blog.katty.in/3025

Recommended Posts

I created an api domain with Spring Framework. Part 2
I created an api domain with Spring Framework. Part 1
I created an Atlassian-like web framework
I made a function to register images with API in Spring Framework. Part 1 (API edition)
I made a function to register images with API in Spring Framework. Part 2 (Client Edition)
I made an iPhone Theremin with Vision framework + AudioKit
Customize REST API error response with Spring Boot (Part 2)
Customize REST API error response with Spring Boot (Part 1)
Link API with Spring + Vue.js
Implement REST API with Spring Boot and JPA (domain layer)
Spring with Kotorin --4 REST API design
Create an app with Spring Boot 2
REST API test with REST Assured Part 2
I implemented an OAuth client with Spring Boot / Security (LINE login)
02. I made an API to connect to MySQL (MyBatis) from Spring Boot
I made a simple search form with Spring Boot + GitHub Search API.
Create an app with Spring Boot
I implemented Rails API with TDD by RSpec. part2 -user authentication-
I wanted to make JavaFX programming easier with the Spring Framework
I tried GraphQL with Spring Boot
I tried Flyway with Spring Boot
Test Spring framework controller with Junit
I made an eco server with scala
Spring Framework study notes [Part 1] DI container
I tried Lazy Initialization with Spring Boot 2.2.0
Configure microservices with Spring Cloud (4): API Gateway
Downgrade an existing app created with rails 5.2.4 to 5.1.6
Create an RSA encryption-enabled JSON API with wicket
I made an API client for Nature Remo
Get Body part of HttpResponse with Filter of Spring
I tried to link JavaFX and Spring Framework.
Get data with api created by curl command
I wanted to gradle spring boot with multi-project
◆ Get API created by Spring Boot from React
Create a web api server with spring boot
Handle JSON in cross domain with Play Framework