Friday, November 10, 2017

Spring framework - Jackson UnrecognizedPropertyException not thrown

Jackson UnrecognizedPropertyException not thrown

This post is to show how to force newer version of Spring (4.1.1.RELEASE and later) to return error when a JSON with unrecognized fields is deserialized.

Setup

Maven
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>4.3.12.RELEASE</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-webmvc</artifactId>
 <version>4.3.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.2</version>
</dependency>

Development

User.java

package com.example.model;

public class User {
    private String id;
    private String name;

    // constructor, setters, getters
}

JSON

{
  “id”: “28b60d1e-c650-11e7-abc4-cec278b6b50a”,
  “name”: “John Smith”,
  “nickname”: “Johnny”
}

Controller.java

package com.example.controller;

@RestController
public class Controller {

    private UserService userService;

    @PutMapping(“/user”)
    public void updateUserInfo(@RequestBody User user) {
        userService.updateUser(user);
    }
}
I expected to see UnrecognizedPropertyException or 400 Bad Request when the JSON was sent in, but it did not happen. Adding the annotation @JsonIgnoreProperties(ignoreUnknown=false) to the POJO had no effect, either. It turns out Spring Framework has changed its default configuration. So in the Spring configuration xml, I have to override its behavior

context-config.xml

<mvc:annotation-driven">
 <mvc:message-converters>
  <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
              <property name="objectMapper">
               <bean class="com.fasterxml.jackson.databind.ObjectMapper"/>
              </property>
  </bean>
 </mvc:message-converters>
</mvc:annotation-driven>

Tuesday, September 26, 2017

Android - set host IP on app

Android - dynamic host IP

I want to test my Android RESTful API requests against the mock web server running on the same PC. The PC has dynamically assigned IP address, so the mock web server might also have different IP address when I restart the server. I could manually change the server IP on Android source code when new IP is assigned, but it’s not practical because not only do I modify the source code, it will also block the tests on daily build machine. The code snippet is to demonstrate how to dynamically set the host IP address on Android.

Setup

  • Android Studio

Development

build.gradle

android {
    . . .
    buildTypes {
        debug {
            buildConfigField "String", "SERVER_ADDR", '\"' + getHostIp() + '\"'
        }
        release {
            . . .
        }
    }
}

def getHostIp() {
    String result = "127.0.0.1";
    Enumeration ifaces = NetworkInterface.getNetworkInterfaces();
    while (ifaces.hasMoreElements()) {
        NetworkInterface iface = ifaces.nextElement();
        if (!iface.isLoopback()) {
            for (InterfaceAddress ifaceAddr : iface.getInterfaceAddresses()) {
                if (ifaceAddr.getAddress().isSiteLocalAddress()) {
                    result = ifaceAddr.getAddress().getHostAddress();
                    break;
                }
            }
        }
    }
    return result;
}

Now the host IP can be obtained from SERVER_ADDR

package com.example;

import static com.example.test.BuildConfig.SERVER_ADDR;

@RunWith(AndroidJUnit4.class)
public class RESTApiTest {
    private final static String MOCK_SERVER = "http://" + SERVER_ADDR + “:5438/API/v1.0/“;

    @Test
    Public void testHelloWorld {
        . . .
    }
}

In case you are running the tests on an actual device, make sure the device is also running on the same subnet.