Sur la base de toutes vos remarques, voici ma proposition qui a fonctionné pour moi:
private final class CustomHttpServletRequest extends HttpServletRequestWrapper {
private final Map<String, String[]> queryParameterMap;
private final Charset requestEncoding;
public CustomHttpServletRequest(HttpServletRequest request) {
super(request);
queryParameterMap = getCommonQueryParamFromLegacy(request.getParameterMap());
String encoding = request.getCharacterEncoding();
requestEncoding = (encoding != null ? Charset.forName(encoding) : StandardCharsets.UTF_8);
}
private final Map<String, String[]> getCommonQueryParamFromLegacy(Map<String, String[]> paramMap) {
Objects.requireNonNull(paramMap);
Map<String, String[]> commonQueryParamMap = new LinkedHashMap<>(paramMap);
commonQueryParamMap.put(CommonQueryParams.PATIENT_ID, new String[] { paramMap.get(LEGACY_PARAM_PATIENT_ID)[0] });
commonQueryParamMap.put(CommonQueryParams.PATIENT_BIRTHDATE, new String[] { paramMap.get(LEGACY_PARAM_PATIENT_BIRTHDATE)[0] });
commonQueryParamMap.put(CommonQueryParams.KEYWORDS, new String[] { paramMap.get(LEGACY_PARAM_STUDYTYPE)[0] });
String lowerDateTime = null;
String upperDateTime = null;
try {
String studyDateTime = new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("dd-MM-yyyy").parse(paramMap.get(LEGACY_PARAM_STUDY_DATE_TIME)[0]));
lowerDateTime = studyDateTime + "T23:59:59";
upperDateTime = studyDateTime + "T00:00:00";
} catch (ParseException e) {
LOGGER.error("Can't parse StudyDate from query parameters : {}", e.getLocalizedMessage());
}
commonQueryParamMap.put(CommonQueryParams.LOWER_DATETIME, new String[] { lowerDateTime });
commonQueryParamMap.put(CommonQueryParams.UPPER_DATETIME, new String[] { upperDateTime });
legacyQueryParams.forEach(commonQueryParamMap::remove);
return Collections.unmodifiableMap(commonQueryParamMap);
}
@Override
public String getParameter(String name) {
String[] params = queryParameterMap.get(name);
return params != null ? params[0] : null;
}
@Override
public String[] getParameterValues(String name) {
return queryParameterMap.get(name);
}
@Override
public Map<String, String[]> getParameterMap() {
return queryParameterMap; // unmodifiable to uphold the interface contract.
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(queryParameterMap.keySet());
}
@Override
public String getQueryString() {
// @see : https://stackoverflow.com/a/35831692/9869013
// return queryParameterMap.entrySet().stream().flatMap(entry -> Stream.of(entry.getValue()).map(value -> entry.getKey() + "=" + value)).collect(Collectors.joining("&")); // without encoding !!
return queryParameterMap.entrySet().stream().flatMap(entry -> encodeMultiParameter(entry.getKey(), entry.getValue(), requestEncoding)).collect(Collectors.joining("&"));
}
private Stream<String> encodeMultiParameter(String key, String[] values, Charset encoding) {
return Stream.of(values).map(value -> encodeSingleParameter(key, value, encoding));
}
private String encodeSingleParameter(String key, String value, Charset encoding) {
return urlEncode(key, encoding) + "=" + urlEncode(value, encoding);
}
private String urlEncode(String value, Charset encoding) {
try {
return URLEncoder.encode(value, encoding.name());
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Cannot url encode " + value, e);
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
throw new UnsupportedOperationException("getInputStream() is not implemented in this " + CustomHttpServletRequest.class.getSimpleName() + " wrapper");
}
}
note: queryString () nécessite de traiter TOUTES les valeurs de chaque KEY et n'oubliez pas d'encodeUrl () lors de l'ajout de vos propres valeurs de param, si nécessaire
En guise de limitation, si vous appelez request.getParameterMap () ou toute autre méthode qui appellerait request.getReader () et commencer à lire, vous éviterez tout autre appel à request.setCharacterEncoding (...)