繁体   English   中英

带有Spring Boot REST控制器和JSON的空字段

[英]null fields with Spring Boot REST controller and JSON

我有一个带有这个Gradle构建文件的Spring Boot应用程序:

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")
}

使用此应用程序文件:

@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();
    }

}

这个配置文件:

@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("");
    }

}

这个控制器接口:

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);

}

和这个控制器实现:

@RestController
public class ControllerImpl implements Controller {

    @Override
    public Test t(Test test) {
        return test;
    }
}

除了从客户端到服务器的JSON序列化之外,一切似乎都能正常工作。 当我执行这个curl命令时:

curl --insecure -H "Authorization: Basic YWRtaW46cGFzcw==" -H "Content-Type: application/json" -X POST -d '{"a":"a","b":"b"}' https://localhost:8443/t

我明白了:

{"a":null,"b":null}

如果我只是在控制器实现中调试,我看到字段为null 如果我像这样修改控制器:

@Override
public Test t(Test test) {
    Test t = new Test();
    t.setA("a");
    t.setB("b");
    return t;
}

我得到了正确的答案:

{"a":"a","b":"b"}

为什么我的应用程序没有正确反序列化测试对象?

您需要在接口中使用@RequestBody注释来获取方法实现:

@RestController 
public class ControllerImpl implements Controller {

    @Override
    public Test t(@RequestBody Test test) {
        return test;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM