init project
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package com.mt.wms.gateway;
|
||||
/*
|
||||
* Copyright (c) 2018.
|
||||
* http://www.ulabcare.com
|
||||
*/
|
||||
|
||||
import com.mt.wms.core.EnableMesCore;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 服务网关
|
||||
*
|
||||
* @author FanYi
|
||||
* @date 2020/07/01
|
||||
* @since 1.0
|
||||
*/
|
||||
@SpringBootApplication(exclude = {})
|
||||
@ComponentScan(basePackages = {
|
||||
"com.mt.wms.gateway",
|
||||
"com.mt.wms.common",
|
||||
"com.mt.wms.passport",
|
||||
"com.mt.wms.upms"
|
||||
|
||||
})
|
||||
@ServletComponentScan("com.mt.wms.gateway.filter")
|
||||
@EnableDiscoveryClient
|
||||
//@EnableFeignClients
|
||||
@RefreshScope
|
||||
@EnableMesCore
|
||||
@EnableScheduling
|
||||
public class MesGatewayApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MesGatewayApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018.
|
||||
* http://www.ulabcare.com
|
||||
*/
|
||||
|
||||
package com.mt.wms.gateway.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务网关配置
|
||||
*
|
||||
* @author jiff
|
||||
* @date 2018/11/1
|
||||
* @since 1.0
|
||||
*/
|
||||
@ConfigurationProperties("wms.gateway")
|
||||
@Validated
|
||||
@Data
|
||||
@Component
|
||||
public class GatewayConfig {
|
||||
@NotNull
|
||||
@Valid
|
||||
private List<String> ignoreAuths = new ArrayList<>();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2018.
|
||||
* http://www.ulabcare.com
|
||||
*/
|
||||
|
||||
package com.mt.wms.gateway.config;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.web.cors.reactive.CorsUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 路由配置
|
||||
*
|
||||
* @author jiff
|
||||
* @date 2018/11/1
|
||||
* @since 1.0
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class RouteConfig {
|
||||
private static final String ALLOWED_HEADERS = "Content-Type, authorization, credential, token, X-Requested-With";
|
||||
private static final String ALLOWED_METHODS = "*";
|
||||
private static final String ALLOWED_ORIGIN = "*";
|
||||
private static final String ALLOWED_EXPOSE = "*";
|
||||
private static final String MAX_AGE = "18000L";
|
||||
|
||||
@Bean
|
||||
public WebFilter corsFilter() {
|
||||
return (ServerWebExchange exchange, WebFilterChain chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
if (CorsUtils.isCorsRequest(request)) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
HttpHeaders headers = response.getHeaders();
|
||||
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, ALLOWED_ORIGIN);
|
||||
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, ALLOWED_METHODS);
|
||||
headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);
|
||||
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, ALLOWED_HEADERS);
|
||||
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, ALLOWED_EXPOSE);
|
||||
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
|
||||
if (request.getMethod() == HttpMethod.OPTIONS) {
|
||||
response.setStatusCode(HttpStatus.OK);
|
||||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
return chain.filter(exchange);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.mt.wms.gateway.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
/**
|
||||
* 服务网关swagger配置
|
||||
*
|
||||
* @author jiff
|
||||
* @date 2018/11/1
|
||||
* @since 1.0
|
||||
*/
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
public class SwaggerConfig {
|
||||
@Bean
|
||||
public Docket passportApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2).groupName("wms-passport")
|
||||
.apiInfo(apiInfo("passport", "统一认证接口"))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.mt.wms.passport"))
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket commonApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2).groupName("wms-common")
|
||||
.apiInfo(apiInfo("common", "公共接口"))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.mt.wms.common"))
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket upmsApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2).groupName("wms-upms")
|
||||
.apiInfo(apiInfo("upms", "通用权限接口"))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.mt.wms.upms"))
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo(String title, String description) {// 创建API的基本信息,这些信息会在Swagger UI中进行显示
|
||||
return new ApiInfoBuilder()
|
||||
.title(title)
|
||||
.description(description)
|
||||
.termsOfServiceUrl("http://www.mt.com")
|
||||
.contact(new Contact("jiff", "", "jiff@ulabcare.com"))
|
||||
.version("1.0")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.mt.wms.gateway.config;
|
||||
|
||||
import com.mt.wms.core.config.CommonConfig;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Configuration
|
||||
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
|
||||
|
||||
private final CommonConfig mCommonConfig;
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/common/**").addResourceLocations("file:" + mCommonConfig.getUploadPath());
|
||||
super.addResourceHandlers(registry);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2018.
|
||||
* http://www.ulabcare.com
|
||||
*/
|
||||
|
||||
package com.mt.wms.gateway.feign;
|
||||
|
||||
import com.mt.wms.gateway.feign.fallback.PassportServiceFallback;
|
||||
import com.mt.wms.core.dto.LoginUser;
|
||||
import com.mt.wms.core.vo.R;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* 统一用户服务
|
||||
*
|
||||
* @author jiff
|
||||
* @date 2018/11/1
|
||||
* @since 1.0
|
||||
*/
|
||||
@FeignClient(value = "wms-passport", fallback = PassportServiceFallback.class)
|
||||
public interface PassportService {
|
||||
/**
|
||||
* 请求资源鉴权
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param method 请求方法
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("authorization")
|
||||
R<LoginUser> authorization(@RequestParam("url") String url, @RequestParam("method") String method);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2018.
|
||||
* http://www.ulabcare.com
|
||||
*/
|
||||
|
||||
package com.mt.wms.gateway.feign.fallback;
|
||||
|
||||
import com.mt.wms.core.dto.LoginUser;
|
||||
import com.mt.wms.core.vo.R;
|
||||
import com.mt.wms.gateway.feign.PassportService;
|
||||
import com.mt.wms.passport.controller.PassportController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 统一用户服务失败回调实现
|
||||
*
|
||||
* @author jiff
|
||||
* @date 2018/11/1
|
||||
* @since 1.0
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PassportServiceFallback implements PassportService {
|
||||
@Autowired
|
||||
PassportController passportController;
|
||||
|
||||
@Override
|
||||
public R<LoginUser> authorization(String url, String method) {
|
||||
return passportController.authorization(url, method);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.mt.wms.gateway.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author jiff
|
||||
* @date 2019/11/27
|
||||
* @since 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@WebFilter(urlPatterns = "/*", filterName = "corsFilter")
|
||||
public class CorsFilter implements Filter {
|
||||
private static final String ALLOWED_HEADERS = "Content-Type, authorization, credential, token, X-Requested-With";
|
||||
private static final String ALLOWED_METHODS = "*";
|
||||
private static final String ALLOWED_ORIGIN = "*";
|
||||
private static final String ALLOWED_EXPOSE = "*";
|
||||
private static final String MAX_AGE = "18000L";
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpRequest = ((HttpServletRequest) request);
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Methods", ALLOWED_METHODS);
|
||||
httpServletResponse.setHeader("Access-Control-Max-Age", MAX_AGE);
|
||||
httpServletResponse.setHeader("Access-Control-Allow-Headers", ALLOWED_HEADERS);
|
||||
httpServletResponse.setHeader("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
|
||||
|
||||
if (httpRequest.getMethod().equalsIgnoreCase(HttpMethod.OPTIONS.name())) {
|
||||
return;
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.mt.wms.gateway.filter;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.mt.wms.core.dto.LoginUser;
|
||||
import com.mt.wms.core.vo.R;
|
||||
import com.mt.wms.gateway.config.GatewayConfig;
|
||||
import com.mt.wms.gateway.feign.PassportService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author jiff
|
||||
* @date 2019/11/27
|
||||
* @since 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@WebFilter(urlPatterns = "/*", filterName = "gatewayFilter")
|
||||
public class GatewayFilter implements Filter {
|
||||
@Autowired
|
||||
@Lazy()
|
||||
private PassportService passportService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private GatewayConfig gatewayConfig;
|
||||
|
||||
private static final String GATEWAY_PREFIX = "/api";
|
||||
|
||||
/**
|
||||
* Called by the web container to indicate to a filter that it is being
|
||||
* placed into service. The servlet container calls the init method exactly
|
||||
* once after instantiating the filter. The init method must complete
|
||||
* successfully before the filter is asked to do any filtering work.
|
||||
* <p>
|
||||
* The web container cannot place the filter into service if the init method
|
||||
* either:
|
||||
* <ul>
|
||||
* <li>Throws a ServletException</li>
|
||||
* <li>Does not return within a time period defined by the web
|
||||
* container</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param filterConfig The configuration information associated with the
|
||||
* filter instance being initialised
|
||||
* @throws ServletException if the initialisation fails
|
||||
*/
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>doFilter</code> method of the Filter is called by the container
|
||||
* each time a request/response pair is passed through the chain due to a
|
||||
* client request for a resource at the end of the chain. The FilterChain
|
||||
* passed in to this method allows the Filter to pass on the request and
|
||||
* response to the next entity in the chain.
|
||||
* <p>
|
||||
* A typical implementation of this method would follow the following
|
||||
* pattern:- <br>
|
||||
* 1. Examine the request<br>
|
||||
* 2. Optionally wrap the request object with a custom implementation to
|
||||
* filter content or headers for input filtering <br>
|
||||
* 3. Optionally wrap the response object with a custom implementation to
|
||||
* filter content or headers for output filtering <br>
|
||||
* 4. a) <strong>Either</strong> invoke the next entity in the chain using
|
||||
* the FilterChain object (<code>chain.doFilter()</code>), <br>
|
||||
* 4. b) <strong>or</strong> not pass on the request/response pair to the
|
||||
* next entity in the filter chain to block the request processing<br>
|
||||
* 5. Directly set headers on the response after invocation of the next
|
||||
* entity in the filter chain.
|
||||
*
|
||||
* @param request The request to process
|
||||
* @param response The response associated with the request
|
||||
* @param chain Provides access to the next filter in the chain for this
|
||||
* filter to pass the request and response to for further
|
||||
* processing
|
||||
* @throws IOException if an I/O error occurs during this filter's
|
||||
* processing of the request
|
||||
* @throws ServletException if the processing fails for any other reason
|
||||
*/
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpRequest = ((HttpServletRequest) request);
|
||||
String requestUri = httpRequest.getRequestURI();
|
||||
if (requestUri.startsWith(GATEWAY_PREFIX)) {
|
||||
requestUri = requestUri.substring(GATEWAY_PREFIX.length());
|
||||
}
|
||||
final String method = httpRequest.getMethod();
|
||||
//忽略鉴权的地址
|
||||
if (isIgnoreAuth(requestUri)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("忽略鉴权的地址={}", requestUri);
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
R<LoginUser> r = passportService.authorization(requestUri, method);
|
||||
|
||||
if (r != null && r.ok()) {
|
||||
if (r.getData() != null) {
|
||||
log.info("loginUser={}", JSON.toJSONString(r.getData()));
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
r = r != null ? r : R.failed();
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.getWriter().print(JSON.toJSONString(r));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the web container to indicate to a filter that it is being
|
||||
* taken out of service. This method is only called once all threads within
|
||||
* the filter's doFilter method have exited or after a timeout period has
|
||||
* passed. After the web container calls this method, it will not call the
|
||||
* doFilter method again on this instance of the filter. <br>
|
||||
* <br>
|
||||
* <p>
|
||||
* This method gives the filter an opportunity to clean up any resources
|
||||
* that are being held (for example, memory, file handles, threads) and make
|
||||
* sure that any persistent state is synchronized with the filter's current
|
||||
* state in memory.
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
private boolean isIgnoreAuth(String requestUri) {
|
||||
for (String ignore : gatewayConfig.getIgnoreAuths()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("ignore auth url is {}", ignore);
|
||||
}
|
||||
// 编译正则表达式,忽略大小写的写法
|
||||
Pattern pattern = Pattern.compile(ignore, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(requestUri);
|
||||
// 查找字符串中是否有匹配正则表达式的字符/字符串
|
||||
if (matcher.find()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user