【问题标题】:Array of objects as parameter in Rest service对象数组作为 Rest 服务中的参数
【发布时间】:2015-04-29 06:18:31
【问题描述】:

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

我得到了这个服务定义:

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

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

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

我也这样定义转换器:

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

}

就你所见,没有太多逻辑,也像这样在 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>  

问题是,每个 json 消息的小片段都会调用转换器类,以一个简单的示例来说明传入消息:

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

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

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}]

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

我也有这样定义的标准 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.MappingJackson2HttpMessageConverter">
    </beans:bean>

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

解决方案

您好,万一其他人为此苦苦挣扎,我设法让一切正常运行。

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

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

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

@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) {

这是调用它的正确方法!

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

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

【问题讨论】:

  • 您只是想将传入的 json 转换为对象列表吗?
  • 我建议使用 POST 服务,它在请求正文中接收 JSON,并使用 Jackson 自动将其映射到 java 对象。
  • rigth @LukeSpringWalker,对象是 RestWord 类型。

标签: java json rest spring-mvc


【解决方案1】:

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

看看:Spring MVC - Why not able to use @RequestBody and @RequestParam together 阅读直到最后一条评论。

【讨论】:

  • 我知道我需要更改StringHttpMessageConverter?没有办法只实现转换器吗?我问是因为我将在我的请求中使用几个不同的对象。我已经更改了添加 @RequestBody 部分的服务的定义,但仍然具有相同的行为
  • 以防万一,我的真实方法有很多参数,不仅仅是数组。
  • 为什么你不创建一个对象来表示你正在接收的数据并使用@RequestBody 来映射它(这等于一个对象对应于所有数据)?这样,您将责任委托给 Spring,但您应该注意这一点,不要将对象传递给应用程序的核心,它只需要存在于控制器层中。
  • 是的,实际上我的问题是对基本概念的误解,但@Luke SpringWalker 为我指明了正确的方向
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多