0

I want to apply "stern" strategy on my rest api endpoint (https://stackoverflow.com/a/20597044/4828427). As parameter i am not using JsonObject but MyObject.

@RequestMapping(value = "/api/v1/authenticate", method = RequestMethod.POST)
    public ResponseEntity<TokenDTO> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) {

So i let spring deserializate json to object and i am using object dirrectly. Example:

authenticationRequest.getUsername();

I am looking for some Utils or annotations to detect if there are any unused json elements in request or not to handle it with proper warning handler.

alibaab
  • 35
  • 3
  • 1
    As an option you can define your custom `ObjectMapper` as a `Bean` and make it fail when `unknown` or `missing` properties are encountered in your json. `new ObjectMapper().configure(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES, Boolean.TRUE).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.TRUE);` – Serg Vasylchak Sep 06 '19 at 12:48
  • Could you clarify what do you expect to get as an output of that validation? A 400 status code? Just log a WARN statement? – pca Sep 06 '19 at 13:05
  • Actually just log or send some validation info to frontend – alibaab Sep 06 '19 at 23:51

1 Answers1

0

You can use @JsonAnySetter like this:

1- you define a BaseRequestDTO class:

public abstract class BaseRequestDTO {
    @JsonAnySetter
    public Map<String, Object> additionalData=new HashMap<>();
}

the field additionalData will hold all json field not in your DTO

2- make your dto extend it, like:

class JwtRequest extends BaseRequestDTO{
   public String  username;
   public string password;
}

3- write an aspect to apply your "stern" strategy:

@Aspect
@Component
public class ControllerArgsValidator {
    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void restController() {
    }
    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void controller() {
    }

    @Around("controller() || restController()")
    public Object validate(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        for (Object arg : args) {
            if (arg instanceof BaseRequestDTO) {
                if((BaseRequestDTO) arg).additionalData.isEmpty())
                    //do what ever;
            }
        }
        return point.proceed();
    }
Nosairat
  • 482
  • 9
  • 20
  • for me was enough to see @JsonAnySetter annotation, but still is good to know how to preprocess controller – alibaab Sep 11 '19 at 08:05