SpringBoot 는 인터페이스 데이터 의 복호화 기능 을 실현 합 니 다.
15028 단어 springboot데이터복호화
인터페이스 에 대한 암호 화 복호화 작업 은 주로 다음 과 같은 두 가지 방식 이 있 습 니 다.
사용자 정의 메시지 변환기
장점:인터페이스 만 실현 하고 설정 이 간단 합 니 다.
약점:같은 유형의 MediaType 만 복호화 할 수 있 고 유연성 이 없습니다.
spring 에서 제공 하 는 인터페이스 RequestBody Advice 와 Response Body Advice 를 사용 합 니 다.
장점:요청 한 Referrer,Header 또는 url 에 따라 판단 하고 특정한 수요 에 따라 암호 화 복호화 할 수 있 습 니 다.
예 를 들 어 한 프로젝트 가 업 그 레이 드 될 때 새로운 개발 기능 의 인 터 페 이 스 는 복호화 해 야 한다.오래된 기능 모듈 이 가기 전에 논리 가 암호 화 되 지 않 으 면 위의 두 번 째 방식 만 선택 할 수 있다.다음은 두 번 째 방식 으로 암호 화,복호화 하 는 과정 을 소개 한다.
2.실현 원리
RequestBody Advice 는@RequestBody 이전에 해 야 할 작업 으로 이해 할 수 있 습 니 다.ResponseBody Advice 는@ResponseBody 이후 에 하 는 작업 으로 이해 할 수 있 습 니 다.따라서 인터페이스 에 복호화 가 필요 할 때@RequestBody 를 사용 하여 프론트 인 자 를 받 기 전에 RequestBody Advice 의 실현 클래스 에서 매개 변 수 를 복호화 할 수 있 습 니 다.작업 이 끝나 면 데 이 터 를 되 돌려 야 할 때,@Response Body 이후 Response Body Advice 의 실현 클래스 에 들 어가 매개 변 수 를 암호 화 할 수 있 습 니 다.
RequestBody Advice 요청 처리 과정:
RequestBody Advice 소스 코드 는 다음 과 같 습 니 다.
public interface RequestBodyAdvice {
boolean supports(MethodParameter methodParameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType);
HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException;
Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
@Nullable
Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
}
RequestBody Advice 구현 클래스 를 호출 하 는 부분 코드 는 다음 과 같 습 니 다.
protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
MediaType contentType;
boolean noContentType = false;
try {
contentType = inputMessage.getHeaders().getContentType();
}
catch (InvalidMediaTypeException ex) {
throw new HttpMediaTypeNotSupportedException(ex.getMessage());
}
if (contentType == null) {
noContentType = true;
contentType = MediaType.APPLICATION_OCTET_STREAM;
}
Class<?> contextClass = parameter.getContainingClass();
Class<T> targetClass = (targetType instanceof Class ? (Class<T>) targetType : null);
if (targetClass == null) {
ResolvableType resolvableType = ResolvableType.forMethodParameter(parameter);
targetClass = (Class<T>) resolvableType.resolve();
}
HttpMethod httpMethod = (inputMessage instanceof HttpRequest ? ((HttpRequest) inputMessage).getMethod() : null);
Object body = NO_VALUE;
EmptyBodyCheckingHttpInputMessage message;
try {
message = new EmptyBodyCheckingHttpInputMessage(inputMessage);
for (HttpMessageConverter<?> converter : this.messageConverters) {
Class<HttpMessageConverter<?>> converterType = (Class<HttpMessageConverter<?>>) converter.getClass();
GenericHttpMessageConverter<?> genericConverter =
(converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter<?>) converter : null);
if (genericConverter != null ? genericConverter.canRead(targetType, contextClass, contentType) :
(targetClass != null && converter.canRead(targetClass, contentType))) {
if (logger.isDebugEnabled()) {
logger.debug("Read [" + targetType + "] as \"" + contentType + "\" with [" + converter + "]");
}
if (message.hasBody()) {
HttpInputMessage msgToUse =
getAdvice().beforeBodyRead(message, parameter, targetType, converterType);
body = (genericConverter != null ? genericConverter.read(targetType, contextClass, msgToUse) :
((HttpMessageConverter<T>) converter).read(targetClass, msgToUse));
body = getAdvice().afterBodyRead(body, msgToUse, parameter, targetType, converterType);
}
else {
body = getAdvice().handleEmptyBody(null, message, parameter, targetType, converterType);
}
break;
}
}
}
catch (IOException ex) {
throw new HttpMessageNotReadableException("I/O error while reading input message", ex);
}
if (body == NO_VALUE) {
if (httpMethod == null || !SUPPORTED_METHODS.contains(httpMethod) ||
(noContentType && !message.hasBody())) {
return null;
}
throw new HttpMediaTypeNotSupportedException(contentType, this.allSupportedMediaTypes);
}
return body;
}
위의 소스 코드 에서converter.canRead()
와message.hasBody()
가 모두 true 일 때beforeBodyRead()
와afterBodyRead()
방법 을 호출 할 수 있 기 때문에 우 리 는 실현 류 의 after Body Read()에 복호화 코드 를 추가 하면 된다.Response Body Advice 처리 응답 과정:
ResponseBody Advice 소스 코드 는 다음 과 같 습 니 다.
public interface ResponseBodyAdvice<T> {
boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);
@Nullable
T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response);
}
Response Body Advice 구현 클래스 를 호출 하 는 부분 코드 는 다음 과 같 습 니 다.
if (selectedMediaType != null) {
selectedMediaType = selectedMediaType.removeQualityValue();
for (HttpMessageConverter<?> converter : this.messageConverters) {
GenericHttpMessageConverter genericConverter =
(converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter<?>) converter : null);
if (genericConverter != null ?
((GenericHttpMessageConverter) converter).canWrite(declaredType, valueType, selectedMediaType) :
converter.canWrite(valueType, selectedMediaType)) {
outputValue = (T) getAdvice().beforeBodyWrite(outputValue, returnType, selectedMediaType,
(Class<? extends HttpMessageConverter<?>>) converter.getClass(),
inputMessage, outputMessage);
if (outputValue != null) {
addContentDispositionHeader(inputMessage, outputMessage);
if (genericConverter != null) {
genericConverter.write(outputValue, declaredType, selectedMediaType, outputMessage);
}
else {
((HttpMessageConverter) converter).write(outputValue, selectedMediaType, outputMessage);
}
if (logger.isDebugEnabled()) {
logger.debug("Written [" + outputValue + "] as \"" + selectedMediaType +
"\" using [" + converter + "]");
}
}
return;
}
}
}
위의 소스 코드 에서 converter.canWrite()가 true 일 때 beforeBody Write()방법 을 호출 할 수 있 기 때문에 우 리 는 이러한 beforeBody Write()에 복호화 코드 를 추가 하면 됩 니 다.실전
spring boot 프로젝트 를 새로 만 듭 니 다.spring-boot-encry 는 다음 단계 로 작 동 합 니 다.
pom.xml 에 jar 도입
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
</dependencies>
요청 매개 변수 복호화 차단 클래스DecryptRequestBody Advice 코드 는 다음 과 같 습 니 다.
/**
*
* * @Author: Java
* @Date: 2019/10/24 21:31
*
*/
@Component
@ControllerAdvice(basePackages = "com.example.springbootencry.controller")
@Slf4j
public class DecryptRequestBodyAdvice implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> selectedConverterType) throws IOException {
return inputMessage;
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
String dealData = null;
try {
//
Map<String,String> dataMap = (Map)body;
String srcData = dataMap.get("data");
dealData = DesUtil.decrypt(srcData);
} catch (Exception e) {
log.error(" !", e);
}
return dealData;
}
@Override
public Object handleEmptyBody(@Nullable Object var1, HttpInputMessage var2, MethodParameter var3, Type var4, Class<? extends HttpMessageConverter<?>> var5) {
log.info("3333");
return var1;
}
}
응답 매개 변수 암호 화 차단 클래스암호 응답 Body Advice 코드 는 다음 과 같 습 니 다.
/**
*
*
* @Author: Java
* @Date: 2019/10/24 21:31
*
*/
@Component
@ControllerAdvice(basePackages = "com.example.springbootencry.controller")
@Slf4j
public class EncryResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object obj, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) {
// ServerHttpRequest ServletServerHttpRequest HttpServletRequest
ServletServerHttpRequest sshr = (ServletServerHttpRequest) serverHttpRequest;
// request ,
HttpServletRequest request = sshr.getServletRequest();
String returnStr = "";
try {
// encry header,
serverHttpResponse.getHeaders().add("encry", "true");
String srcData = JSON.toJSONString(obj);
//
returnStr = DesUtil.encrypt(srcData);
log.info(" ={}, ={}, ={}", request.getRequestURI(), srcData, returnStr);
} catch (Exception e) {
log.error(" !", e);
}
return returnStr;
}
새 controller 클래스TestController 코드 는 다음 과 같 습 니 다.
/** * @Author: Java
* @Date: 2019/10/24 21:40
*/
@RestController
public class TestController {
Logger log = LoggerFactory.getLogger(getClass());
/**
*
*/
@RequestMapping(value = "/sendResponseEncryData")
public Result sendResponseEncryData() {
Result result = Result.createResult().setSuccess(true);
result.setDataValue("name", "Java ");
result.setDataValue("encry", true);
return result;
}
/**
*
*/
@RequestMapping(value = "/getRequestData")
public Result getRequestData(@RequestBody Object object) {
log.info("controller object={}", object.toString());
Result result = Result.createResult().setSuccess(true);
return result;
}
}
다른 종 류 는 원본 코드 에 있 고 뒤에 github 주소 가 있 습 니 다.테스트
액세스 응답 데이터 암호 화 인터페이스
postman 보 내기 요청http://localhost:8888/sendResponseEncryData을 사용 하면 반환 데이터 가 암호 화 되 었 음 을 볼 수 있 습 니 다.캡 처 요청 은 다음 과 같 습 니 다.
응답 데이터 암호 화 캡 처
배경 에 도 관련 로 그 를 인쇄 합 니 다.내용 은 다음 과 같 습 니 다.
인터페이스=/sendResponseEncryData
원본 데이터
={"data":{"encry":true,"name":"Java "},"success":true}
암호 화 된 데이터=vJc26g3SQRU9gAJdG7rhnAx6Ky/IhgioAgdwi6aLMMtyynAB4nEbMxvDsKEPNIa5bQaT7ZAImAL7
3VeicCuSTA==액세스 요청 데이터 복호화 인터페이스
postman 보 내기 요청http://localhost:8888/getRequestData을 사용 하면 요청 데이터 가 복호화 되 었 음 을 볼 수 있 습 니 다.캡 처 요청 은 다음 과 같 습 니 다.
데이터 복호화 요청 캡 처
배경 에 도 관련 로 그 를 인쇄 합 니 다.내용 은 다음 과 같 습 니 다.
={"data":"VwLvdE8N6FuSxn/jRrJavATopaBA3M1QEN+9bkuf2jPwC1eSofgahQ=="}
={"name":"Java ","des":" "}
밟 은 구덩이복호화 요청 파 라 메 터 를 테스트 할 때 요청 체 는 반드시 데이터 가 있어 야 합 니 다.그렇지 않 으 면 클래스 트리거 복호화 작업 을 호출 하지 않 습 니 다.
이 SpringBoot 에서 인터페이스 데이터 의 복호화 기능 을 어떻게 유연 하 게 실현 하 는 지 에 대한 기능 이 모두 실현 되 었 습 니 다.문제 가 있 으 면 댓 글 소통 을 환영 합 니 다!
전체 원본 주소:https://github.com/suisui2019/springboot-study
총결산
위 에서 말 한 것 은 소 편 이 소개 한 SpringBoot 가 인터페이스 데이터 의 복호화 기능 을 실현 하 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin Springboot -- 파트 14 사용 사례 REST로 전환하여 POST로 JSON으로 전환前回 前回 前回 記事 の は は で で で で で で を 使っ 使っ 使っ て て て て て リクエスト を を 受け取り 、 reqeustbody で 、 その リクエスト の ボディ ボディ を を 受け取り 、 関数 内部 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.