0

I am facing a strange issue, I have a controller and I have a method which handles put request. The code for controller looks like this:


@RestController
@RequestMapping("/test")
public class TestController {

    @PutMapping(path = "/test/service")
    public Result test(
            @RequestBody TestObject testObj) {
        log.info("Received  request with data {}", testObj.toString());
        try {
            String data = "get from service";
            if (data != null) {
                Result result = new Result();
                result.setSuccess(true);

                result.setSuccessResult(response);
                return result;
            } 
        }

    }

Here is my testObject:

@JsonIgnoreProperties(ignoreUnknown=true)
public class TestObj { 
    
    @NotNull(message = "Should not be null")
    private Integer sequence;
    
    private String message;
    
    private String userId;
}

Now when I make the following request:

curl --location -g --request PUT '{{baseUrl}}/test/test/service' \
--header 'Content-Type: application/json' \
--header 'Authorization: asdasdasdadadasdadadsadasa' \
--data-raw '{
    "sequence":1,
    "message":"  "
}'

I see that "message" field in TestObj is null in logs though I am passing an empty string. Here is a sample output:

TestController:xx - Received request with data TestObj [sequence=1, message=null, userId=null]

Can anyone help me with this?

Update

The solutions in the other link do not work for me.

Update 2

Interceptor code:

public class Interceptor implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
                filterConfig.getServletContext());
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        HttpServletRequest req = (HttpServletRequest) request;
        try {

            String ipAddress = request.getRemoteAddr();
            String url = ((HttpServletRequest) request).getRequestURL().toString();
            String body = extractPostRequestBody(req);
            ObjectMapper objectMapper = new ObjectMapper();
            TestObj testObj = objectMapper.readValue(body, TestObj.class);

            LOG.info("IP " + ipAddress + ", Time " + new Date().toString() + "  url " + url);
            LOG.info("Body: {}", body);
            LOG.info("Test Request: " + testObj);
}

String extractPostRequestBody(HttpServletRequest request) {
        if ("PUT".equalsIgnoreCase(request.getMethod())) {
            Scanner s = null;
            try {
                s = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\\A");
            } catch (IOException e) {
                e.printStackTrace();
            }

            return s != null && s.hasNext() ? s.next() : "";
        }
        return "";
    }
}

Aman Kush
  • 91
  • 2
  • 11
  • 1
    Assuming you are using Jackson, can you show its configuration? My guess is that you have `ACCEPT_EMPTY_STRING_AS_NULL_OBJECT` deserialization feature enabled. – João Dias Jan 18 '22 at 19:35
  • Try adding this to your class: `@JsonInclude(Include.NON_NULL)`. If that works, and you generally want this behaviour, you can configure it globally. – Bohemian Jan 18 '22 at 19:38
  • @JoãoDias Jackson is just added on the classpath via dependency. I believe this feature is enabled by default. Any idea how can I disable it? – Aman Kush Jan 18 '22 at 19:41
  • It is not enabled by default --> https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_EMPTY_STRING_AS_NULL_OBJECT – João Dias Jan 18 '22 at 19:42
  • @JoãoDias Ok thanks, in that case, I am not enabling it anywhere. – Aman Kush Jan 18 '22 at 20:02
  • Then it should work. What happens if you send `userId` in the request? – João Dias Jan 18 '22 at 20:06
  • UserId as empty string or a proper value? If I send it as a proper value, it still gets populated but message is still null. – Aman Kush Jan 18 '22 at 20:08
  • In fact, what happens if you send a proper value in `message`? – João Dias Jan 18 '22 at 20:10
  • There is no issue in that case, it gets populated properly. – Aman Kush Jan 18 '22 at 20:11
  • @JoãoDias And FYI, I have an interceptor before the Controller, I tried to log the request body there, the value is proper there before getting deserialised to custom object but when it reaches the controller, at that point it is null. – Aman Kush Jan 18 '22 at 20:15
  • Can you add the interceptor code to the question? – João Dias Jan 18 '22 at 20:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241186/discussion-between-aman-kush-and-joao-dias). – Aman Kush Jan 18 '22 at 20:20
  • The code looks weird. Is that all? I guess not because the first try has no catch. Please include the complete code. – João Dias Jan 18 '22 at 20:31
  • Maybe you are missing a `chain.doFilter(request, response);` call in your `Interceptor`. – João Dias Jan 18 '22 at 22:31

0 Answers0