Spring mvc RestTemplate postForObject не отправляет параметр в REST API

У меня есть REST API. Я делаю клиента. Я настроил весеннюю безопасность для аутентификации моей службой отдыха. Мой контроллер REST API

@RequestMapping(value = "/login", method = RequestMethod.POST, headers="content-type=application/json")
public @ResponseBody
UserDetails loginUser(WebRequest request)
        throws LoginOrPasswordException {
    logger.info("login user");
    logger.info(request);
    String username = request.getParameter("username");
    logger.info(username);
    UserDetails uDetails = userRepository.login(username);
    System.out.println(uDetails.getPassword());
    return uDetails;
}

Контекст приложения API

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<mvc:annotation-driven />

<context:component-scan base-package="com.zayats." />

<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean
                class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
        </list>
    </property>
</bean>

<!-- Http Json MessageConverter -->
<bean id="jsonConverter"
    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json" />
</bean>

<import resource="jdbc-config.xml" />

Next is client method with restTemplate

HashMap<String, String> params = new HashMap<String, String>();
    params.put("username", username);
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<?> httpEntity = new HttpEntity<Object>(params, requestHeaders);
    logger.info("Create map and doing request.");
    UserDetails matchingUser = restTemplate.postForObject(
            "http://localhost:8080/ApiFamilyShoplist/user/login", httpEntity,
            UserDetails.class);

Конфигурация шаблона отдыха

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
    <property name="messageConverters">
        <list>
            <bean id="jsonConverter"
                class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes" value="application/json" />
            </bean>
        </list>
    </property>
</bean>

Когда я вызываю свой API с помощью postForObject в контроллере API, он не получает никаких параметров. Пожалуйста, дайте мне совет, как заставить его отправлять данные в API. Спасибо.


person O.Zaiats    schedule 04.06.2013    source источник


Ответы (1)


Вам нужно иметь еще один параметр в вашем методе, чтобы принять строковый параметр и аннотировать его с помощью @RequestBody (внутри подписи метода):

@ResponseBody
@Consumes("text/plain")
public UserDetails loginUser(WebRequest request, @RequestBody String userName)

Кроме того, если вы передаете строку, я предлагаю добавить простой конвертер строк http в конвертеры остального шаблона и аннотировать метод сервера с помощью @Consumes(text/plain). Таким образом, вы получите его как простую строку.

person Avi    schedule 04.06.2013
comment
@RequestBody каким методом? В контроллере API? - person O.Zaiats; 05.06.2013
comment
@user2391060 user2391060 Вы пытаетесь получить параметр запроса (POST или GET), однако вы публикуете JSON. В объекте HttpServletRequest не будет параметра. Поэтому вам нужно сообщить Spring, что ему нужно преобразовать тело запроса в объект JSON. @RequestBody Map<String, Object> params должен быть параметром вашего метода контроллера. - person Pavel Horal; 05.06.2013
comment
Я думаю, что нет ничего плохого в отправке JSON... предложение использовать строку - довольно радикальное решение. Для строки вы можете просто использовать параметры запроса. - person Pavel Horal; 05.06.2013
comment
Также то, что сказал @PavelHoral, сработает. Но вместо простой строки вы получите карту ключей (имен параметров), которые сопоставляются с объектами (фактические параметры). Если я правильно понимаю. - person Avi; 05.06.2013
comment
@Avi - просто предположение, что Джексон может превратиться в Map<String, Object>. Если нет, потребуется другой класс (например, ObjectNode) - person Pavel Horal; 05.06.2013
comment
@PavelHoral - Не всегда вы хотите, чтобы пользователь запрашивал параметры. Я говорю из собственного опыта. У нас была большая строка, включающая символы i18n (разные языки). Это не то, что вы передаете в URL-адресе. Но я согласен, что во многих случаях URL-адреса достаточно - person Avi; 05.06.2013
comment
@PavelHoral - Вы правы насчет неупорядочивания в Map<String, Object. - person Avi; 05.06.2013
comment
Спасибо. Попробую через 30 минут. Но, следуя твоим словам, мне придется @RequestBody Map<String, Object> params всеми способами получать какие-либо данные от клиента? - person O.Zaiats; 05.06.2013
comment
Обычно, если вы передаете объект и у вас есть класс для представления такого объекта на сервере (скажем, вызов User), вы можете сделать что-то вроде: public void method(@RequestBody User user) И вы получите фактический объект, уже преобразованный из строки. В вашем случае вы просто передаете строку, поэтому, я думаю, такой карты достаточно. - person Avi; 05.06.2013
comment
Но если я пытаюсь отправить, например List<String>, что мне делать? - person O.Zaiats; 05.06.2013
comment
Дженерики в этом случае проблематичны. Насколько я знаю, лучшим решением будет использование String[] вместо этого. - person Avi; 05.06.2013
comment
@RequestBody Map<String, Object> params работает. Всем огромное спасибо. :) - person O.Zaiats; 05.06.2013