How to Resolve Uri Encoding Problem in Spring-Boot

How to resolve URI encoding problem in spring-boot?

Without encoding from your client side - you could still achieve this if you follow any of the following strategies by encoding before the request is processed in the servlet:

  • use Spring preprocessor bean to preprocess the controller endpoint request
  • use Spring AspectJ to preprocess the controller endpoint request
  • use Spring servlet filter to preprocess the controller endpoint request

With any of the above cross-cutting strategies, you could encode the request URL and pass back to the endpoint.

For example below is one implmentation using Filter. You could possibly do some caching there if you need better performance.

@Component
public class SomeFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeFilter.class);

@Override
public void init(final FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletRequest modifiedRequest = new SomeHttpServletRequest(request);
filterChain.doFilter(modifiedRequest, servletResponse);
}

@Override
public void destroy() {

}

class SomeHttpServletRequest extends HttpServletRequestWrapper {
HttpServletRequest request;

SomeHttpServletRequest(final HttpServletRequest request) {
super(request);
this.request = request;
}

@Override
public String getQueryString() {
String queryString = request.getQueryString();
LOGGER.info("Original query string: " + queryString);

try {
// You need to escape all your non encoded special characters here
String specialChar = URLEncoder.encode("%", "UTF-8");
queryString = queryString.replaceAll("\\%\\%", specialChar + "%");

String decoded = URLDecoder.decode(queryString, "UTF-8");
LOGGER.info("Modified query string: " + decoded);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

return queryString;
}

@Override
public String getParameter(final String name) {
String[] params = getParameterMap().get(name);
return params.length > 0 ? params[0] : null;
}

@Override
public Map<String, String[]> getParameterMap() {
String queryString = getQueryString();
return getParamsFromQueryString(queryString);
}

@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(getParameterMap().keySet());
}

@Override
public String[] getParameterValues(final String name) {
return getParameterMap().get(name);
}

private Map<String, String[]> getParamsFromQueryString(final String queryString) {
String decoded = "";
try {
decoded = URLDecoder.decode(queryString, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String[] params = decoded.split("&");
Map<String, List<String>> collect = Stream.of(params)
.map(x -> x.split("="))
.collect(Collectors.groupingBy(
x -> x[0],
Collectors.mapping(
x -> x.length > 1 ? x[1] : null,
Collectors.toList())));

Map<String, String[]> result = collect.entrySet().stream()
.collect(Collectors.toMap(
x -> x.getKey(),
x -> x.getValue()
.stream()
.toArray(String[]::new)));

return result;
}
}
}

spring resttemplate url encoding

There is no easy way to do this. URI template variables are usually meant for path elements or a query string parameters. You're trying to pass a host. Ideally, you'd find a better solution for constructing the URI. I suggest Yuci's solution.

If you still want to work with Spring utilities and template expansion, one workaround is to use UriTemplate to produce the URL with the URI variables as you have them, then URL-decode it and pass that to your RestTemplate.

String url = "http://{enpointUrl}?method=logout&session={sessionId}";
URI expanded = new UriTemplate(url).expand(endpointUrl, sessionId); // this is what RestTemplate uses
url = URLDecoder.decode(expanded.toString(), "UTF-8"); // java.net class
template.getForObject(url, Object.class);


Related Topics



Leave a reply



Submit