#java
Вопрос:
Я хочу использовать RestTemplate на основе OKHttp3 для удаленного вызова интерфейса queryByIds
для получения основной информации о пользователе.
@Configuration
public class CloudConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
}
способ реализации queryByIds
приведен ниже:
@GetMapping("/queryByIds")
public GraceJSONResult queryByIds(@RequestParam String userIds) {
if (StringUtils.isBlank(userIds)) {
return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
}
List<String> userIdList = JsonUtils.jsonToList(userIds, String.class);
ArrayList<AppUserVO> userVOList = new ArrayList<>();
assert userIdList != null;
userIdList.forEach(id -> {
AppUserVO userInfo = getBasicUserInfo(id);
userVOList.add(userInfo);
});
return GraceJSONResult.ok(userVOList);
}
Вот код бизнеса, http://user.mootalk.com
который переключен на localhost
использование коммутаторов:
// Get the basic information of each user and put it in userVOList
String userServerUrlExecute = "http://user.mootalk.com:8003/user/queryByIds?userIds=" JsonUtils.objectToJson(publisherIdSet);
System.out.println(userServerUrlExecute);
// the debugger paused
ResponseEntity<GraceJSONResult> entity =
restTemplate.getForEntity(userServerUrlExecute, GraceJSONResult.class);
Вот мой класс util:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
/**
* json converter
*/
public class JsonUtils {
private static final ObjectMapper MAPPER = new ObjectMapper();
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Когда я отлаживал код ,он не входил в queryByIds
метод, и консоль напечатала userServerUrlExecute
следующее:
Но если вы создадите запрос в Postman следующим образом: http://user.mootalk.com:8003/user/queryByIds?userIds=210726G71HSY2YY8
, он может войти в queryByIds
метод, но userIdList
он оказался нулевым.
Если вы создадите запрос в Postman следующим образом : http://user.mootalk.com:8003/user/queryByIds?userIds=["210726G71HSY2YY8","200628AFYM7AGWPH"]
,он хорошо работает.
Так что же не так с моим кодом при передаче параметра?
Более позднее сообщение1:
- Теперь последний запрос на создание не вошел
queryByIds
как в адресную строку Chrome, так и в почтальона, он выдал400 Bad Request
; - Я заменил
@RequestParam
на@RequestBody
inqueryByIds
, он все равно бросил400 Bad Request
Последнее сообщение2:
Комментарии:
1. Что вы, вероятно, хотите сделать, так это закодировать его
base64
и передать,userIds
а затем декодировать с другой стороны.2. Как сказал @Popeye, проблема в том, что вам нужно закодировать свой JSON, если вы используете его в качестве параметра url. Тем не менее, я бы сказал, что передача JSON в качестве параметра GET довольно неприятна. Чтобы решить вашу проблему и сделать ваш API немного проще для понимания, я бы передал данные JSON в теле запроса
3. @m-alorda прав, просто потому, что ты можешь, не значит, что ты должен. Что-то еще, что следует учитывать, если вы хотите перейти по URL-адресу, я бы, вероятно, подумал о том, чтобы сделать это в виде списка, разделенного запятыми, вместо JSON. Задайте себе вопрос, получаете ли вы что-нибудь от того, что это JSON, если это просто список идентификаторов? Почему ты просто не можешь это сделать
?userIds=210726G71HSY2YY8,200628AFYM7AGWPH
? Если вы посмотрите на свой код, вы ничего не получите, если он будет JSON.4. @Popeye это также возможно, просто добавьте несколько значений в значение параметра без JSON. Тем не менее, чтобы позволить spring справиться с этим, я бы предложил использовать URI как таковой:
?userIds=XXXXXamp;userIds=YYYYY
5. @m-alorda , позже я использовал твой метод , и он сработал.
Ответ №1:
На самом деле я бы не стал просто передавать JSON в параметр запроса, как вы делаете, это неприятно и на самом деле не соответствует никакому стандарту API RESTFUL.
У вас есть 4 варианта, как я это вижу:
- Перейдите к запросу HTTP POST и передайте данные JSON в тело запроса (рекомендуется и следует рекомендациям).
- Если по каким-либо причинам ваши требования таковы, что это должен быть запрос HTTP GET и должен быть параметр запроса, то вам необходимо кодировать JSON в base64 перед его передачей.
?userIds=W1wiMjEwNzI2RzcxSFNZMllZOFwiLFwiMjAwNjI4QUZZTTdBR1dQSFwiXQ==
- Опять же, если это должен быть запрос HTTP GET, но он не обязательно должен быть JSON, я бы добавил разделенный запятыми список идентификаторов в параметр запроса
?userIds=210726G71HSY2YY8,200628AFYM7AGWPH
- Просто запросите 1 идентификатор пользователя за раз.
Ваши требования, вероятно, будут определять подход, который вы изберете.