4

Currently a request method receives a encoded token as parameter (this token is a String but not JSON or anything like that). This token then gets decoded to a data class.

@GetMapping(value = "/api/xyz")
public ResponseEntity<XYZ> xyz(@NotBlank String token) {
    Data data = Token.parse(token);
    ...
}

Is it possible to write a annotation similar to how @RequestBody works that converts a parameter into something else?

The request should just look like that instead:

@GetMapping(value = "/api/xyz")
public ResponseEntity<XYZ> xyz(@TokenParser Data data) {
    ...
}

This class / annotation should contain the code necessary to convert the token (String) to my data class. The request method should just have the converted data class as parameter.

Spenhouet
  • 6,556
  • 12
  • 51
  • 76
  • You'll need to write a converter for it using `ParamConverterProvider` – Nicholas K Sep 28 '18 at 14:08
  • https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-typeconversion – JB Nizet Sep 28 '18 at 14:08
  • It seems I was very unclear. The token is not JSON or anything like that. The token is encoded. I need a special method where I can code the conversion myself. The links you posted doesn't seem related. – Spenhouet Sep 28 '18 at 14:16
  • well actuall you need filter or aop when request come to dispatcher it will triggered and now i am ganna talk about custom annotation so you can use aop so easy to use and you can define around annotation for it and when method is triggered it wil be immediately return to aop around method and then you can check this annotation is blah blah so do some business there – Mithat Konuk Sep 28 '18 at 14:35
  • I think you are referring custom annotations like @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.FIELD}) public @interface TokenConverter { String convertToken(); } – kj007 Sep 28 '18 at 14:39
  • @JBNizet The thing is I don't see that as a solution for me. I don't want to write a InitBinder for every controller. That seems to be required by the solution suggested with your link. – Spenhouet Sep 28 '18 at 14:49
  • Then put the InitBinder in a ControllerAdvice, as the documentation suggests. Or use a Formatter, as the documentation also suggests. – JB Nizet Sep 28 '18 at 14:50
  • Thank you for your suggestions. I found a much simpler way that is exactly like what I was looking for. I wrote an answer for it. – Spenhouet Sep 28 '18 at 15:05

1 Answers1

5

I solved it with the spring-boot Converter.

import javax.inject.Inject;

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@Component
public class TokenConverter implements Converter<String, Data> {

    private final TokenParser tokenParser;

    @Inject
    public TokenConverter(TokenParser TokenParser) {
        this.tokenParser = tokenParser;
    }

    @Override
    public Data convert(String token) {
        return tokenParser.parse(token);
    }
}

Just add such a converter anywhere in your project. The mapping is managed by spring-boot.

New request:

@GetMapping(value = "/api/method")
public ResponseEntity<Data> method(@RequestParam("token") Data data) {
    ...
}

For more information: https://www.baeldung.com/spring-mvc-custom-data-binder

I hope it helps someone else.

Spenhouet
  • 6,556
  • 12
  • 51
  • 76
  • I also came across this solution from baeldung but im really interested in how it can be done with a custom annotation. – S.Tushinov Sep 28 '18 at 15:16