Spring MVC의 @RequestParam에 대한 사용자 지정 변환기
Spring rest 컨트롤러 메서드에 암호화된 String as Query 매개 변수를 가져오는 중입니다.
나는 문자열이 어떤 주석을 기반으로 메소드에 도달하기 전에 해독하고 싶었습니다.@Decrypt
아래와 같이
@RequestMapping(value = "/customer", method = RequestMethod.GET)
public String getAppointmentsForDay(@RequestParam("secret") @Decrypt String customerSecret) {
System.out.println(customerSecret); // Needs to be a decrypted value.
...
}
사용자 정의Formatter
이 사용 사례에서 올바른 접근 방식?
아니면 사용자 정의를 사용해야 합니까?HandlerMethodArgumentResolver
?
의 사용자 정의 구현org.springframework.format.Formatter
는 이 사용 사례에 대한 유효한 접근 방식입니다.이것이 Spring 자체가 날짜, 통화, 숫자 스타일 등에 대한 형식을 구현하는 방법입니다.
단계:
주석 선언:
Decrypt
:import java.lang.annotation.*; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) public @interface Decrypt { }
선언 an
AnnotationFormatterFactory
새 주석을 사용합니다.import org.springframework.context.support.EmbeddedValueResolutionSupport; import org.springframework.format.AnnotationFormatterFactory; import org.springframework.format.Formatter; import org.springframework.format.Parser; import org.springframework.format.Printer; import java.text.ParseException; import java.util.Collections; import java.util.HashSet; import java.util.Locale; import java.util.Set; public class DecryptAnnotationFormatterFactory extends EmbeddedValueResolutionSupport implements AnnotationFormatterFactory<Decrypt> { @Override public Set<Class<?>> getFieldTypes() { Set<Class<?>> fieldTypes = new HashSet<>(); fieldTypes.add(String.class); return Collections.unmodifiableSet(fieldTypes); } @Override public Printer<String> getPrinter(Decrypt annotation, Class<?> fieldType) { return configureFormatterFrom(annotation); } @Override public Parser<String> getParser(Decrypt annotation, Class<?> fieldType) { return configureFormatterFrom(annotation); } private Formatter<String> configureFormatterFrom(Decrypt annotation) { // you could model something on the Decrypt annotation for use in the decryption call // in this example the 'decryption' call is stubbed, it just reverses the given String // presumaby you implementaion of this Formatter will be different e.g. it will invoke your encryption routine return new Formatter<String>() { @Override public String print(String object, Locale locale) { return object; } @Override public String parse(String text, Locale locale) throws ParseException { return new StringBuilder(text).reverse().toString(); } }; } }
이 포맷터 공장을 웹 컨텍스트에 등록합니다.
import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class WebConfigurer extends WebMvcConfigurerAdapter { @Override public void addFormatters(FormatterRegistry registry) { super.addFormatters(registry); registry.addFormatterForFieldAnnotation(new DecryptAnnotationFormatterFactory()); } }
바로 그겁니다.
위와 같은 조건 하에서, 모든 사용은@RequestParam
의 자격이 있는.@Decrypt
를 통해 전달될 것입니다.parse()
에서 선언된 방법DecryptAnnotationFormatterFactory
거기서 암호 해독 호출을 실행할 수 있습니다.
이를 증명하기 위해 다음 테스트를 통과합니다.
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = YourController.class)
public class YourControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void theSecretRequestParameterWillBeConverted() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/customer?secret=abcdef")).andExpect(status().isOk()).andReturn();
// the current implementation of the 'custom' endpoint returns the value if the secret request parameter and
// the current decrypt implementation just reverses the given value ...
assertThat(mvcResult.getResponse().getContentAsString(), is("fedcba"));
}
}
이 점에서 HandlerMethodArgumentResolver가 가장 좋습니다.
- 주석을 작성합니다.
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Decrypt {
String value();
}
- 사용자 지정 처리기 메서드 인수 확인기 만들기:
public class DecryptResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(Decrypt.class) != null;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
Decrypt attr = parameter.getParameterAnnotation(Decrypt.class);
String encrypted = webRequest.getParameter(attr.value());
String decrypted = decrypt(encrypted);
return decrypted;
}
private String decrypt(String encryptedString) {
// Your decryption logic here
return "decrypted - "+encryptedString;
}
}
- 해결 프로그램을 등록합니다.
@Configuration
@EnableMvc // If you're not using Spring boot
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new DecryptResolver());
}
}
- Voila, 암호 해독된 매개 변수가 있습니다.더 이상 @RequestParam을 사용할 필요가 없습니다.
@RequestMapping(value = "/customer", method = RequestMethod.GET)
public String getAppointmentsForDay(@Decrypt("secret") String customerSecret) {
System.out.println(customerSecret); // Needs to be a decrypted value.
...
}
다음을 추가하여 시도할 수 있습니다.CharacterEncodingFilter
와 함께init-param
encoding
UTF-8
에web.xml
파일. 이 예제를 확인하십시오.
그래도 작동하지 않으면 아래 매개 변수를 위에 추가하여 인코딩을 강제로 적용할 수 있습니다.init-param
.
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
그게 당신에게 효과가 있는지 알려주세요.
암호 해독된 데이터를 데이터 전송 개체로 래핑하는 경우 Spring's Converter 프레임워크를 사용할 수 있습니다.
public class Decrypted { // data transfer object
private final String value;
public Decrypted(String value){
this.value = value;
}
public String get(){
return value;
}
}
인터페이스 구현org.springframework.core.convert.converter.Converter
추가합니다.@Component
주석
@Component
public class DecryptConverter implements Converter<String, Decrypted> {
@Override
public Decrypted convert(String value) {
return new Decrypted(decrypt(value)); // you implement "decrypt"
}
}
등록합니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new DecryptConverter());
}
}
그런 다음 다음 매개 변수에 래퍼 유형(암호 해독됨)을 사용합니다.
@RequestMapping(value = "/customer", method = RequestMethod.GET)
public String getAppointmentsForDay(@RequestParam("secret") Decrypted customerSecret) {
System.out.println(customerSecret.get()); // decrypted value
}
https://www.baeldung.com/spring-enum-request-param 도 참조하십시오.
언급URL : https://stackoverflow.com/questions/46728972/custom-converter-for-requestparam-in-spring-mvc
'programing' 카테고리의 다른 글
Angular - 'HammerJ를 찾을 수 없습니다.에스 (0) | 2023.08.04 |
---|---|
양식 인증과 Windows 인증 혼합 (0) | 2023.08.04 |
선 세그먼트를 특정 거리만큼 확장 (0) | 2023.08.04 |
오레오에 알림이 표시되지 않음 (0) | 2023.08.04 |
'자산' 폴더에서 sdcard로 파일을 복사하는 방법은 무엇입니까? (0) | 2023.08.04 |