I have an Spring Boot application with this Gradle build file:
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
apply plugin: 'war'
sourceCompatibility = 1.7
targetCompatibility = 1.7
version = '1.0'
buildscript {
ext {
springBootVersion = '1.1.9.RELEASE'
}
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.9.RELEASE")
}
}
jar {
manifest {
attributes 'Implementation-Title': 'Server', 'Implementation-Version': version
}
}
war {
baseName = 'gs-convert-jar-to-war'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-snapshot" }
maven { url "http://maven.springframework.org/milestone" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-tomcat:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-aop:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-test:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-security:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}")
compile("org.springframework.data:spring-data-rest-webmvc")
compile("org.hsqldb:hsqldb")
compile("com.google.guava:guava:17.0")
compile("org.apache.httpcomponents:httpclient:4.3.4")
compile("commons-io:commons-io:2.4")
testCompile("junit:junit")
}
With this application file:
@EnableAutoConfiguration
@Configuration
@ComponentScan
@Import({ BasicSecurityConfiguration.class, HTTPSTomcatConfiguration.class,
MultiPartConfiguration.class })
public class Application extends RepositoryRestMvcConfiguration {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// use JSON
@Override
public ObjectMapper halObjectMapper() {
return new ResourcesMapper();
}
}
this configuration files:
@Configuration
@EnableWebSecurity
public class BasicSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// no cache
http.requestCache().requestCache(new NullRequestCache());
// use HTTPS
http.requiresChannel().anyRequest().requiresSecure();
http.portMapper().http(8080).mapsTo(8443);
// this replaces the web security http configuration
http.authorizeRequests().antMatchers("/**").authenticated().and()
.httpBasic();
// disable CSRF
http.csrf().disable();
}
@Autowired
protected void registerAuthentication(
final AuthenticationManagerBuilder auth) throws Exception {
// FIXME create a full user registry
// in-memory users
auth.inMemoryAuthentication().withUser("admin").password("pass")
.authorities("admin", "user").and().withUser("user")
.password("pass").authorities("user");
}
}
@Configuration
public class HTTPSTomcatConfiguration {
@Bean
EmbeddedServletContainerCustomizer containerCustomizer(
@Value("8443") final int port,
@Value("keystore.p12") Resource keystoreFile,
@Value("tomcat") final String alias,
@Value("localhost") final String keystorePass,
@Value("PKCS12") final String keystoreType) throws Exception {
final String absoluteKeystoreFile = keystoreFile.getFile()
.getAbsolutePath();
return new EmbeddedServletContainerCustomizer() {
public void customize(ConfigurableEmbeddedServletContainer container) {
TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container;
tomcat.addConnectorCustomizers(new TomcatConnectorCustomizer() {
public void customize(Connector connector) {
connector.setPort(port);
connector.setSecure(true);
connector.setScheme("https");
Http11NioProtocol proto = (Http11NioProtocol) connector
.getProtocolHandler();
proto.setSSLEnabled(true);
proto.setKeystoreFile(absoluteKeystoreFile);
proto.setKeyAlias(alias);
proto.setKeystorePass(keystorePass);
proto.setKeystoreType(keystoreType);
}
});
}
};
}
}
@Configuration
@EnableConfigurationProperties(MultipartProperties.class)
public class MultiPartConfiguration {
@Bean
public MultipartConfigElement multipartConfigElement() {
return new MultipartConfigElement("");
}
}
this controller interface:
public interface Controller {
@RequestMapping(value = "/t", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Test t(@RequestBody Test test);
}
and this controller implementation:
@RestController
public class ControllerImpl implements Controller {
@Override
public Test t(Test test) {
return test;
}
}
Everything seems to work fine, except the JSON serialization from client to server. When I execute this curl
command:
curl --insecure -H "Authorization: Basic YWRtaW46cGFzcw==" -H "Content-Type: application/json" -X POST -d '{"a":"a","b":"b"}' https://localhost:8443/t
I get:
{"a":null,"b":null}
If I debug just in the controller implementation I see the fields as null
. If I modify the controller like this:
@Override
public Test t(Test test) {
Test t = new Test();
t.setA("a");
t.setB("b");
return t;
}
I get the correct answer:
{"a":"a","b":"b"}
Why my app is not deserializing Test object properly?
You have @RequestBody annotation in your interface you need to have it on the method implementation:
@RestController
public class ControllerImpl implements Controller {
@Override
public Test t(@RequestBody Test test) {
return test;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With