java 对象数组作为 Rest 服务中的参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28749785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:07:24  来源:igfitidea点击:

Array of objects as parameter in Rest service

javajsonrestspring-mvc

提问by Camilo Casadiego

I have a rest service which receives an array of objects, and I need to convert the json info back into the object List; my stack is build on top of Spring 4

我有一个接收对象数组的休息服务,我需要将 json 信息转换回对象列表;我的堆栈建立在 Spring 4 之上

I got this service definition:

我得到了这个服务定义:

@RequestMapping(value = "/services/crud/dangers/createDanger", method = RequestMethod.GET)
    public @ResponseBody GenericServiceReturn createDanger(
            @RequestParam(value = "postionId", required = true) Long positionId,
            @RequestParam(value = "dangerName", required = true) String dangerName,
            @RequestParam(value = "type", required = true) Integer type,
            @RequestParam(value = "description", required = true) String description,
            @RequestParam(value = "words", required = true) List<RestWord> words)

As you can see, the parameter words is a List of RestWord, which is defined like this:

可以看到,参数words是一个RestWord的List,定义如下:

public class RestWord {
    private long id = -1;
    private String name;
    private long type = -1;

Also I've defined the converter like this:

我也像这样定义了转换器:

public class RestWordConverter implements Converter<String, RestWord>{
    private static final Logger log = LoggerFactory
            .getLogger(RestWordConverter.class);

    @Override
    public RestWord convert(String text) {
        // TODO Auto-generated method stub
        log.info(text);
        return new RestWord();
    }

}

not much logic so far as you can see, also got the converter registered in mvc context like this.

就你所见,没有多少逻辑,也像这样在 mvc 上下文中注册了转换器。

<mvc:annotation-driven conversion-service="conversionService" />

<beans:bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" >
        <beans:property name="converters">
            <beans:list>
                <beans:bean class="co.com.lineascontrol.core.endpoints.converters.RestWordConverter"/>
            </beans:list>
        </beans:property>
    </beans:bean>  

The problem is, that the converter class is called for each little piece of the json message, to illustrate that, a simple example, for an incoming message:

问题是,转换器类为 json 消息的每一小部分调用,为了说明这一点,一个简单的例子,对于传入的消息:

String words = "[{\"id\":0,\"name\":instalar,\"type\":-1},{\"id\":0,\"name\":ventilacion,\"type\":-1},{\"id\":0,\"name\":tunel,\"type\":-1}]";

I'm getting this at the server output:

我在服务器输出中得到这个:

c.c.l.c.e.c.RestWordConverter - [{"id":0
c.c.l.c.e.c.RestWordConverter - "name":instalar
c.c.l.c.e.c.RestWordConverter - "type":-1}
c.c.l.c.e.c.RestWordConverter - {"id":0
c.c.l.c.e.c.RestWordConverter - "name":ventilacion
c.c.l.c.e.c.RestWordConverter - "type":-1}
c.c.l.c.e.c.RestWordConverter - {"id":0
c.c.l.c.e.c.RestWordConverter - "name":tunel
c.c.l.c.e.c.RestWordConverter - "type":-1}]

Which means the converter function is called one time for every part of the message, and by doing this is impossible to convert the incoming string to the specific object.

这意味着对于消息的每一部分都调用一次转换器函数,并且通过这样做不可能将传入的字符串转换为特定的对象。

I also have the standard Json converters defined like this:

我也有这样定义的标准 Json 转换器:

<beans:bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <beans:property name="messageConverters">
            <beans:list>
                <beans:ref bean="jsonMessageConverter" />
            </beans:list>
        </beans:property>
    </beans:bean>

    <!-- Configure bean to convert JSON to POJO and vice versa -->
    <beans:bean id="jsonMessageConverter"
        class="org.springframework.http.converter.json.MappingHymanson2HttpMessageConverter">
    </beans:bean>

I believe that the converter should be defined as json converter, and not as a conversion service for mvc, but I haven't managed to find examples or documentation about this.

我认为应该将转换器定义为 json 转换器,而不是作为 mvc 的转换服务,但我还没有找到有关此的示例或文档。

Solution

解决方案

Hi, in case someone else is struggling with this I managed to get everything up and running.

嗨,如果其他人正在为此苦苦挣扎,我设法让一切正常运行。

First of all, if you are new to Rest, I found this simple article explaining basic, but very important stuff:

首先,如果您是 Rest 的新手,我发现这篇简单的文章解释了基本但非常重要的内容:

http://www.drdobbs.com/web-development/restful-web-services-a-tutorial/240169069?pgno=1

http://www.drdobbs.com/web-development/restful-web-services-a-tutorial/240169069?pgno=1

After that, I understood most of my problems, so at the end this is my service interface:

之后,我明白了我的大部分问题,所以最后这是我的服务接口:

@RequestMapping(value = "/services/crud/dangers/createDanger", method = RequestMethod.POST)
    public @ResponseBody GenericServiceReturn createDanger(
            @RequestBody List<RestWord> words,
            @RequestParam(value = "postionId", required = true) Long positionId,
            @RequestParam(value = "dangerName", required = true) String dangerName,
            @RequestParam(value = "type", required = true) String type,
            @RequestParam(value = "description", required = true) String description) {

And here is the proper way to calle it!

这是调用它的正确方法!

List<RestWord> restWordList = new ArrayList<RestWord>();

            //put some values in the list! or whatever object you are using

            url = "http://localhost:8080/LineasControllBussinesLayer/rest/services/crud/dangers/createDanger";

            //add the uri params
            Map<String, Object> requestParams = new HashMap<String, Object>();
            requestParams.put("postionId", 1l);
            requestParams.put("dangerName", dangerName);
            requestParams.put("type", DANGER_TYPE.ACTIVITIE);
            requestParams.put("description", "actividad repeligrosa");

            // Create the request body as a MultiValueMap

            System.out.println(restWordList);
            //see how the HttpEntity is created with the first parameter as the object, and the second are the header, in my case I use the headers to aunteticate
            HttpEntity<List<RestWord>> entity2 = new HttpEntity<List<RestWord>>(restWordList, headers);


            //then just call the service!!!
            System.out.println(restTemplate.postForObject(url, entity2, String.class, requestParams));

Please keep in mind that this is just test code, the actual requests should be wrapped into a request object, and everything should go inside the request body

请记住,这只是测试代码,实际的请求应该被包装到一个请求对象中,所有的东西都应该放在请求正文中

采纳答案by Luke SpringWalker

I'd recommend to use @Resquestbodyto map the json to an object. Be aware to combine it with @RequestParamas it may work or not given a version, and it has to be in certain order (try to avoid the @ResquestParamin this case).

我建议使用@Resquestbody将 json 映射到对象。请注意将它与@RequestParam它结合,因为它可能工作或没有给出版本,并且它必须按一定的顺序(@ResquestParam在这种情况下尽量避免)。

Take a look at: Spring MVC - Why not able to use @RequestBody and @RequestParam togetherRead until the last comment.

看一看:Spring MVC - 为什么不能一起使用@RequestBody 和@RequestParam阅读直到最后一条评论。