利用filter过虑用户请求URI显示对应页面内容

本文介绍了一个简单的URI过滤器实现,通过在web.xml中配置过滤器,可以针对不同的URI请求,跳转到相应的JSP页面。具体实现了对index和select两个URI的过滤,分别展示index.jsp和select.jsp的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的:只是想验证一下filter对URI的过滤

流程讲解:浏览器请求URI,所有请求都走过虑器,在过滤器中处理符合某种请求的URI然后显示对应的页面内容

有2个JSP页面:

index.jsp:

  <body>
    This is index page. 111111111111111111111<br>
    <ul>
        <li>1111111111</li>
        <li>2222222222</li>
    </ul>
  </body>

select.jsp:

<body>
     <ul>
        <li>3333333</li>
        <li>444444444</li>
    </ul>
  </body>

filter类UrlFilter.java

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest=(HttpServletRequest) request;
        HttpServletResponse httpServletResponse=(HttpServletResponse) response;
        String requestUrl = httpServletRequest.getRequestURI();
        String ContextPath =httpServletRequest.getContextPath();
        System.out.println(requestUrl+"========"+ContextPath);
        String ContextPath1=ContextPath+"/";
        String uri=requestUrl.replace(ContextPath1, "");
        System.out.println("uri==========="+uri);
        
        //String info = uri.substring(0, uri.indexOf("."));
        if("index".equals(uri)){
            httpServletRequest.getRequestDispatcher("index.jsp").forward(httpServletRequest, httpServletResponse);
        }else if("select".equals(uri)){
            httpServletRequest.getRequestDispatcher("select.jsp").forward(httpServletRequest, httpServletResponse);
        }
    }

web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name></display-name>
 
  <filter>
      <filter-name>urlFilter</filter-name>
      <filter-class>filter.UrlFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>urlFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

浏览器访问uri:

1、http://localhost:8080/struts/index显示index.jsp页面内容

2、http://localhost:8080/struts/select显示select.jsp页面内容

转载于:https://www.cnblogs.com/sincoolvip/p/6086406.html

<think>好的,我现在需要帮助用户找到在Spring Cloud Gateway中实现GlobalFilter并打印请求参数、请求头、Cookie、URI和响应结果的示例代码,同时包含所需的import引用。首先,我得回忆一下Spring Cloud Gateway的相关知识,尤其是关于GlobalFilter的部分。 用户提到了引用[1]、[2]、[3],其中引用[3]提到了如何注入Sentinel过滤器作为GlobalFilter,这可能是一个参考。用户的需求是创建一个自定义的GlobalFilter,用来记录请求的各种信息,比如参数、头、Cookie、URI,以及响应结果。同时需要示例代码包含import语句。 首先,GlobalFilter在Spring Cloud Gateway中是一个接口,需要实现它的filter方法。在该方法中,可以获取ServerWebExchange对象,进而访问请求和响应的详细信息。不过,需要注意的是,在Gateway中,处理的是ServerHttpRequest和ServerHttpResponse,而不是传统的HttpServletRequest。 接下来,考虑如何打印请求参数。请求参数可以通过ServerHttpRequest的getQueryParams()方法获取,这会返回一个MultiValueMap,其中包含所有的查询参数。然后需要将这些参数转换为字符串格式记录下来。 请求头可以通过ServerHttpRequest的getHeaders()方法获取,同样是一个MultiValueMap。需要遍历所有头名称,获取对应的值。 Cookie的话,可以通过ServerHttpRequest的getCookies()方法获取,返回的是MultiValueMap<String, HttpCookie>。需要提取每个Cookie的名称和值。 URI可以通过ServerHttpRequest的getURI()方法直接获取,然后调用toString()方法转换为字符串。 至于响应结果,由于响应体是一个Flux<DataBuffer>,直接读取可能会有挑战,因为数据流只能被消费一次。通常的做法是使用修改响应体的装饰器,例如使用ServerHttpResponseDecorator来包装响应,以便在响应体写入时捕获内容。不过,记录响应体可能会影响性能,并且需要注意处理大文件或流式数据的情况。 此外,用户可能希望日志在请求处理前和响应返回后都能被记录,所以需要在过滤器的处理链中,先记录请求信息,然后使用chain.filter(exchange).then()来处理响应后的日志记录。 现在,关于import部分,需要引入相关的Spring类和接口,比如org.springframework.cloud.gateway.filter.GlobalFilter,org.springframework.core.Ordered(用于设置过滤器顺序),reactor.core.publisher.Mono,以及ServerWebExchange,ServerHttpRequest,ServerHttpResponse等。此外,处理响应体可能需要引入ServerHttpResponseDecorator和相关的DataBufferUtils工具类。 需要注意的是,在打印响应体时,要确保不会干扰正常的数据流。通常的做法是将数据缓冲读取为字节数组,转换为字符串,然后记录日志。但必须小心处理,避免内存问题,特别是在处理大响应时。此外,可能需要限制记录的响应体长度,避免日志过大。 另外,用户可能希望看到完整的示例代码,包括类定义、方法实现以及必要的注解,比如@Component或者通过@Bean来注册过滤器。根据引用[3],使用@Bean和@Order来定义过滤器的顺序,这可能是一个好的做法。 在代码结构方面,自定义的GlobalFilter需要实现GlobalFilter和Ordered接口,以便指定过滤器的执行顺序。在filter方法中,先处理请求信息,记录日志,然后使用chain.filter(exchange)继续处理,之后在.then()方法中处理响应信息。 现在,整合这些思路,编写一个示例类,包含所有必要的导入和日志记录步骤。确保代码正确处理请求和响应,并处理可能的异常情况。同时,需要注意日志的输出级别,避免在生产环境中产生过多日志。 最后,检查是否有遗漏的部分,比如Cookie的处理是否正确,URI是否包括路径和查询参数,响应体的读取是否正确,以及import语句是否完整。确保示例代码能够直接运行,或者用户可以根据示例进行调整。</think>以下是在Spring Cloud Gateway中实现GlobalFilter并打印请求信息的示例代码: ```java import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.nio.charset.StandardCharsets; @Component public class LoggingGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 记录请求信息 ServerHttpRequest request = exchange.getRequest(); // 打印请求基础信息 System.out.println("Request URI: " + request.getURI()); System.out.println("Request Method: " + request.getMethod()); // 打印请求头 System.out.println("Request Headers: "); request.getHeaders().forEach((name, values) -> System.out.println(name + ": " + values)); // 打印Cookie System.out.println("Cookies: "); request.getCookies().forEach((name, cookies) -> cookies.forEach(cookie -> System.out.println(name + "=" + cookie.getValue()))); // 打印查询参数 System.out.println("Query Params: "); request.getQueryParams().forEach((name, values) -> System.out.println(name + ": " + values)); // 包装响应对象以记录响应信息 ServerHttpResponse originalResponse = exchange.getResponse(); ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) { @Override public Mono<Void> writeWith(org.springframework.core.io.buffer.DataBuffer body) { DataBufferUtils.retain(body); String responseBody = StandardCharsets.UTF_8.decode(body.asByteBuffer()).toString(); System.out.println("Response Body: " + responseBody); return super.writeWith(body); } }; return chain.filter(exchange.mutate().response(decoratedResponse).build()) .then(Mono.fromRunnable(() -> { // 打印响应状态码 System.out.println("Response Status: " + exchange.getResponse().getStatusCode()); // 打印响应头 System.out.println("Response Headers: "); exchange.getResponse().getHeaders().forEach((name, values) -> System.out.println(name + ": " + values)); })); } @Override public int getOrder() { return -1; // 设置过滤器执行顺序 } } ``` 注意事项: 1. 响应体记录仅适用于非流式响应,大文件可能造成内存压力 2. 生产环境建议使用SLF4J代替System.out 3. 需要配合`spring-boot-starter-webflux`依赖 4. 响应体拦截功能需谨慎使用,可能影响性能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值