spring boot 拦截器获取controller返回的数据_@RestController vs @Controller
时间: 2023-08-03 09:55:53 浏览: 416
在Spring Boot中,拦截器可以用于在请求到达Controller之前或之后执行某些操作。无论是@RestController还是@Controller,拦截器都可以获取到Controller的返回值。
但是,对于@RestController和@Controller的区别,需要注意以下两点:
1.返回值类型不同
- @RestController注解的Controller方法返回的是JSON/XML等数据,适用于API接口的开发。
- @Controller注解的Controller方法返回的是视图(View),适用于Web页面的开发。
2.@RestController注解相当于@ResponseBody + @Controller
- @RestController注解会自动将Controller方法返回的数据转换为JSON/XML等格式的数据,并将其输出到响应体中,不需要使用@ResponseBody注解。
- @Controller注解需要使用@ResponseBody注解才能将数据输出到响应体中。
因此,在拦截器中获取Controller返回值时,需要根据Controller的注解类型进行不同的处理。如果是@RestController,直接获取响应体中的数据即可;如果是@Controller,则需要获取ModelAndView对象并从中获取数据。
相关问题
Java Spring boot 拦截器中添加返回响应结果 sm4加密
<think>好的,我现在要处理用户的问题:在Java Spring Boot拦截器中添加返回响应结果的SM4加密。首先,我需要确认用户的需求是什么。他们想在拦截器中处理响应数据,然后进行加密,特别是使用国密的SM4算法。
首先,我应该回忆一下Spring Boot拦截器的相关知识。拦截器主要用于预处理和后处理请求,可以在Controller执行前后进行操作。这里用户关注的是响应结果,所以应该是在afterCompletion方法,或者更可能是在preHandle或postHandle方法里处理响应数据?不对,postHandle是在Controller方法执行之后,视图渲染之前,可以修改ModelAndView。而afterCompletion是在请求完成之后,通常用于资源清理。因此,用户可能需要使用postHandle方法来修改响应内容,或者使用一个响应包装类来捕获响应数据。
但Spring的拦截器默认可能无法直接修改响应体,因为响应可能已经被提交。这时候可能需要使用Filter或者使用ContentCachingResponseWrapper来缓存响应数据,以便后续处理。不过用户提到的是拦截器,所以可能需要结合拦截器和ResponseBodyAdvice来实现。或者用户可能混淆了拦截器和过滤器的概念,需要明确两者的区别。
不过,用户明确说是拦截器,所以可能需要用HandlerInterceptor,但是要修改响应体的话,可能更合适的做法是使用ResponseBodyAdvice接口,它可以在控制器方法返回后,对响应体进行处理,比如加密。或者结合使用拦截器和ResponseBodyAdvice?
接下来,SM4加密的实现。需要确认用户是否已经有了SM4的工具类,或者需要引入相关的依赖。国密算法SM4的实现可能需要Bouncy Castle库或者其他国密算法的实现库。例如,Bouncy Castle提供了对SM4的支持,用户需要添加相应的依赖,或者使用国内的一些工具包,比如org.bouncycastle:bcprov-jdk15on。
然后,具体步骤可能是这样的:
1. 创建一个拦截器,实现HandlerInterceptor接口,或者使用ResponseBodyAdvice来对响应体进行处理。
2. 在拦截器的postHandle方法中,获取响应数据,进行加密处理。但是这里可能遇到问题,因为默认的响应流可能无法被重复读取,所以需要使用ContentCachingResponseWrapper来包装原始的HttpServletResponse,这样可以从缓存中读取响应内容。
3. 或者,使用ResponseBodyAdvice的beforeBodyWrite方法,在响应体写入之前进行加密处理。这种方式可能更直接,因为ResponseBodyAdvice专门用于处理响应体数据。
4. 实现SM4加密的逻辑,将原始响应内容加密后返回。
需要明确哪种方式更合适。例如,ResponseBodyAdvice允许在控制器返回结果后,对响应体进行处理,这样可以直接修改返回的数据,然后进行加密。而拦截器更适用于处理请求前后的通用逻辑,但修改响应体可能不太直接。
因此,可能更推荐使用ResponseBodyAdvice来实现。不过用户明确提到拦截器,可能需要解释两种方法,并给出相应的实现步骤。
接下来,具体实现步骤:
对于使用ResponseBodyAdvice:
1. 添加SM4加密所需的依赖,如Bouncy Castle。
2. 创建一个类实现ResponseBodyAdvice接口,并重写相关方法,支持对特定返回类型或路径的处理。
3. 在beforeBodyWrite方法中,获取原始的响应体,使用SM4加密,然后返回加密后的数据。
4. 配置这个Advice生效,可能需要使用@ControllerAdvice注解。
对于使用拦截器:
1. 创建一个拦截器类,实现HandlerInterceptor接口。
2. 在preHandle或postHandle方法中,将HttpServletResponse替换为ContentCachingResponseWrapper,以便后续读取响应内容。
3. 在afterCompletion方法中,获取缓存的响应内容,进行加密处理,并重新写入响应流。
4. 需要注意处理响应流的关闭和提交问题,避免重复写入。
不过,使用拦截器处理响应体可能较为复杂,因为拦截器的执行顺序和响应流的处理可能受限。而ResponseBodyAdvice更专注于响应体的处理,可能更简单。
另外,关于SM4加密的具体实现,用户可能需要生成密钥,选择合适的加密模式(如CBC或ECB),填充方式(如PKCS7Padding),以及处理IV(初始化向量)等。需要确保加密和解密的参数一致,比如密钥、模式、填充方式等。
因此,总结步骤:
1. 引入Bouncy Castle依赖或其他SM4实现库。
2. 创建ResponseBodyAdvice实现类,使用@ControllerAdvice注解。
3. 在beforeBodyWrite方法中,将原始响应数据转换为加密后的数据。
4. 编写SM4加密工具类,处理加密逻辑。
5. 测试验证加密是否正确,确保客户端能够解密。
可能还需要处理异常情况,比如加密失败,响应数据为空的情况。同时,要确保加密后的数据格式正确,比如Base64编码,以便传输。
最后,可能需要提供示例代码,说明如何实现ResponseBodyAdvice和SM4加密工具类,以及相关的配置步骤。同时提醒用户注意密钥管理,加密模式的选择,以及性能影响等注意事项。</think>在Spring Boot中,通过拦截器对响应结果进行SM4加密的实现可分为以下步骤:
---
### **1. 添加依赖**
首先引入SM4加密所需的库(如Bouncy Castle):
```xml
<dependency>
<groupId.org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
```
---
### **2. 创建SM4加密工具类**
编写SM4加密工具类,示例如下:
```java
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
import java.util.Base64;
public class SM4Util {
static {
Security.addProvider(new BouncyCastleProvider());
}
// SM4加密(ECB模式,PKCS7填充)
public static String encrypt(String data, String key) throws Exception {
byte[] keyBytes = key.getBytes();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "SM4");
Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
}
```
---
### **3. 实现响应体加密拦截器**
由于拦截器直接操作响应体较复杂,推荐使用`ResponseBodyAdvice`接口:
```java
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@ControllerAdvice
public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
private static final String SM4_KEY = "your-16-byte-secret"; // 16字节密钥
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true; // 对所有响应生效
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
try {
String originalData = body.toString();
return SM4Util.encrypt(originalData, SM4_KEY);
} catch (Exception e) {
throw new RuntimeException("SM4加密失败", e);
}
}
}
```
---
### **4. 处理特殊情况**
- **非字符串响应**:若响应为JSON对象,需先序列化为字符串再加密。
- **异常处理**:添加全局异常处理器,避免加密失败导致服务不可用。
---
### **5. 配置密钥管理**
- 密钥应从安全配置(如Vault、配置中心)动态获取,避免硬编码。
- 加密模式建议使用`CBC`(需处理IV)而非`ECB`以提高安全性。
---
### **6. 验证结果**
发送请求后,响应应为加密后的Base64字符串:
```plaintext
HTTP/1.1 200 OK
Content-Type: text/plain
qZ6N3mJ7T0KjRn8lPp2vXg==
```
---
### **注意事项**
1. **性能影响**:加密操作可能增加响应时间,建议对敏感数据选择性加密。
2. **客户端解密**:确保客户端能正确解密(如使用相同SM4算法和密钥)。
3. **HTTPS推荐**:结合HTTPS传输,避免密钥泄露。
---
通过以上步骤,即可在Spring Boot中实现对响应结果的SM4加密。
spring boot拦截器过滤器
Spring Boot中的拦截器和过滤器有一些区别。拦截器是Spring MVC自带的,不依赖于servlet容器,而过滤器依赖于servlet容器。拦截器是基于Java的反射机制,而过滤器是基于函数的回调。拦截器只能对action请求起作用,而过滤器可以对几乎所有的请求起作用。拦截器可以获取IOC容器中的bean,而过滤器不可以。拦截器是由Spring MVC提供的,可以在Controller中访问服务层。而过滤器是JavaEE标准,只需依赖servlet API,不需要依赖Spring。在Spring Boot中配置拦截器可以使用@WebFilter注解,并在启动类中加上@ServletComponentScan注解指定扫描的包。\[1\]\[2\]\[3\]
#### 引用[.reference_title]
- *1* [Springboot--拦截器、过滤器 区别,作用,实现方法](https://blog.csdn.net/Dark_AK44/article/details/123746613)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item]
- *2* *3* [springboot过滤器和拦截器](https://blog.csdn.net/qq_42076204/article/details/125215984)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item]
[ .reference_list ]
阅读全文
相关推荐
















