好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用Filter拦截器如何实现请求跨域转发

Filter拦截器实现请求跨域转发

因为公司项目需求,项目中前端请求需要通过一个类似中转的服务转发(请求在该服务中会重新包装一些通用参数)

在使用Filter实现转发后特做一次记录

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

package com.unicloud.cce.Filter;

import com.alibaba.fastjson.JSON;

import com.unicloud.cce测试数据mon.RestfulEntity;

import com.unicloud.cce.service.CloudosService;

import org.apache测试数据mons.io.IOUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.*;

import org.springframework.stereotype.Component;

import org.springframework.util.AntPathMatcher;

import org.springframework.util.StringUtils;

import org.springframework.web.client.RestTemplate;

import javax.servlet.*;

import javax.servlet.annotation.WebFilter;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.*;

 

/**

  * @author skyxt

  * Created 2019-06-11 18:46

  * Email skyxt.yang@gmail测试数据

  */

@WebFilter (filterName = "authFilter" , urlPatterns = { "/*" })

@Component

public class RequestFilter implements Filter {

 

     //该处配置需要转发的路径

     public static final Set<String> FILTER_URL = Collections.unmodifiableSet( new HashSet<>(Arrays.asList(

             "/config/*"

     )));

 

     @Autowired

     private RestTemplate restTemplate;

     @Autowired

     private CloudosService cloudosService; 

     private final static Logger logger = LoggerFactory.getLogger(RequestFilter. class );

     @Override

     public void init(FilterConfig filterConfig) throws ServletException {

     }

 

     @Override

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

         if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {

             return ;

         }

         HttpServletRequest req = (HttpServletRequest) request;

         HttpServletResponse rsp = (HttpServletResponse) response;

         AntPathMatcher matcher = new AntPathMatcher();

         Optional<String> cloudIp = Optional.empty();

//        for (String url : FILTER_URL) {

//            if (matcher.match(url, req.getRequestURI().substring(req.getContextPath().length()))) {

//                cloudIp = cloudosService.cloudosList("", "").stream().filter(cloudos ->

//                        cloudos.getId().equals(((HttpServletRequest) request).getHeader("cloudId"))

//                ).map(Cloudos::getCloudIp).findFirst();

//            }

//        }

         cloudIp = Optional.of( "localhost" );

         if (cloudIp.isPresent()) {

             switch (req.getMethod()) {

                 case "GET" : {

                     request(req, rsp, HttpMethod.GET, cloudIp.get());

                     break ;

                 }

                 case "POST" : {

                     request(req, rsp, HttpMethod.POST, cloudIp.get());

                     break ;

                 }

                 case "PUT" : {

                     request(req, rsp, HttpMethod.PUT, cloudIp.get());

                     break ;

                 }

                 case "PATCH" : {

                     request(req, rsp, HttpMethod.PATCH, cloudIp.get());

                     break ;

                 }

                 case "DELETE" : {

                     request(req, rsp, HttpMethod.DELETE, cloudIp.get());

                     break ;

                 }

                 default :{

                     logger.error( "unknow request method:" + req.getMethod());

                     rsp.setCharacterEncoding( "UTF-8" );

                     try (PrintWriter out = rsp.getWriter()) {

                         out.write( "请求方法未知" );

                     } catch (Exception e1) {

                         logger.error(e1.getMessage() + e1);

                     }

                 }

             }

         } else {

             chain.doFilter(request, response);

         }

     }

 

     @Override

     public void destroy() {

     }

 

     private void request(HttpServletRequest req, HttpServletResponse rsp, HttpMethod method, String cloudIp) throws IOException {

         rsp.setCharacterEncoding( "UTF-8" );

         String requestBody = IOUtils.toString(req.getInputStream(), "UTF-8" );

         Object body = null ;

         if (StringUtils.hasText(requestBody)) {

             body = JSON.parse(requestBody);

         }

         HttpHeaders headers = new HttpHeaders();

         Enumeration<String> headerNames = req.getHeaderNames();

         while (headerNames.hasMoreElements()) {

             String name = headerNames.nextElement();

             headers.add(name, req.getHeader(name));

         }

         String url;

         if (StringUtils.hasText(req.getQueryString())) {

             url = String.format(

                     "http://%s:15120%s?%s" ,

                     cloudIp,

                     req.getRequestURI().substring(req.getContextPath().length()),

                     req.getQueryString()

                     );

         } else {

             url = String.format(

                     "http://%s:15120%s" ,

                     cloudIp,

                     req.getRequestURI().substring(req.getContextPath().length())

             );

         }

         HttpEntity<Object> httpEntity = new HttpEntity<>(body, headers);

         ResponseEntity<RestfulEntity> exchange = null ;

         try {

             exchange = restTemplate.exchange(

                     url,

                     method,

                     httpEntity,

                     RestfulEntity. class

             );

         } catch (Exception e) {

             logger.error(e.getMessage(), e);

             try (PrintWriter out = rsp.getWriter()) {

                 out.write( "请求异常" );

             } catch (Exception e1) {

                 logger.error(e1.getMessage() + e1);

             }

         }

         if (exchange != null ) {

             exchange.getStatusCode();

             rsp.setStatus(exchange.getStatusCodeValue());

             exchange.getHeaders().entrySet().stream().forEach(entry -> {

                 String value = entry.getValue().toString();

                 rsp.addHeader(entry.getKey(), value.substring( 1 , value.length()- 1 ));

             });

             try (PrintWriter out = rsp.getWriter()) {

                 out.write(JSON.toJSONString(exchange.getBody()));

             } catch (Exception e) {

                 logger.error(e.getMessage(), e);

             }

         } else {

             logger.info( "error: URL:" + "http://" + cloudIp + ":15120" + req.getRequestURI().substring(req.getContextPath().length()));

             try (PrintWriter out = rsp.getWriter()) {

                 out.write( "请求异常" );

             } catch (Exception e1) {

                 logger.error(e1.getMessage() + e1);

             }

         }

     }

}

使用filter解决跨域

在web.xml配置拦截器

?

1

2

3

4

5

6

7

8

< filter >

  < filter-name >servletFilterTest</ filter-name >

  < filter-class >cn.test.intercepter.ServletFilterTest</ filter-class >

</ filter >

< filter-mapping >

  < filter-name >servletFilterTest</ filter-name >

  < url-pattern >/*</ url-pattern >

</ filter-mapping >

过滤器代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

public class ServletFilterTest implements Filter {

     @Override

     public void init(FilterConfig filterConfig) throws ServletException {

     }

     @Override

     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

         HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

         httpServletRequest.getSession();

         HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

         httpResponse.setHeader( "Access-Control-Allow-Origin" , "*" );

         httpResponse.setHeader( "Access-Control-Allow-Methods" , "*" );

         httpResponse.setHeader( "Access-Control-Max-Age" , "3600" );

         httpResponse.setHeader( "Access-Control-Allow-Headers" ,

                 "Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie" );

         httpResponse.setHeader( "Access-Control-Allow-Credentials" , "true" );

         httpResponse.setHeader( "Content-type" , "application/json" );

         httpResponse.setHeader( "Cache-Control" , "no-cache, must-revalidate" );

         if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {

             return ;

         }

         filterChain.doFilter(httpServletRequest, httpResponse);

     }

     @Override

     public void destroy() {

     }

}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/weixin_37774620/article/details/91544007

查看更多关于使用Filter拦截器如何实现请求跨域转发的详细内容...

  阅读:27次