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
Converting Exponential Value in Java to a Number Format
The Import Org.Junit Cannot Be Resolved
How to Use Different Jsonproperty on Serialize & Deserialize Using Jackson API
How to Loop Through List of Webelements and Select One Webelement With a Condition
Split Comma Separated Values in Java, Int and String
Spring Security Configuration Filter Any Requests Except a Specific Endpoint
How to Handle Errors in Spring-Webflux
Get the Nearest Date to Specific from the List of Dates
How to Find Max Duplicate Number Count in Given Array Using for Loop
In Java, How to Combine Two Json Arrays of Objects
Javax.Net.Ssl.Sslexception: Certificate Doesn't Match Any of the Subject Alternative Names
Getting Data from Incoming Json in a Java Servlet
Automatically Size Jpanel Inside Jframe
Handling Static Variables in Multithreaded Java Program
Converting Number Representing a Date in Excel to a Java Date Object
Placing a Jlabel At a Specific X,Y Coordinate on a Jpanel