如何解决Spring-boot中的URI编码问题?

我正在使用spring-boot来托管http请求服务。

@RequestMapping("/extract")

@SuppressWarnings("unchecked")

@ResponseBody

public ExtractionResponse extract(@RequestParam(value = "extractionInput") String input) {

// LOGGER.info("input: " + input);

JSONObject inputObject = JSON.parseObject(input);

InputInfo inputInfo = new InputInfo();

//Object object = inputObject.get(InputInfo.INPUT_INFO);

JSONObject object = (JSONObject) inputObject.get(InputInfo.INPUT_INFO);

String inputText = object.getString(InputInfo.INPUT_TEXT);

inputInfo.setInputText(inputText);

return jnService.getExtraction(inputInfo);

}

出现%符号时,如下所示,它出现了错误:

 http://localhost:8090/extract?extractionInput={"inputInfo":{"inputText":"5.00%"}}

错误消息如下:

2018-10-09 at 19:12:53.340 [http-nio-8090-exec-1] INFO  org.apache.juli.logging.DirectJDKLog [180] [log] - Character decoding failed. Parameter [extractionInput] with value [{"inputInfo":{"inputText":"5.0022:%225.00%%22}}] has been ignored. Note that the name and value quoted here may be corrupted due to the failed decoding. Use debug level logging to see the original, non-corrupted values.

Note: further occurrences of Parameter errors will be logged at DEBUG level.

2018-10-09 at 19:12:53.343 [http-nio-8090-exec-1] WARN org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver [140] [resolveException] - Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'extractionInput' is not present]

如何配置URI编码以在我的spring-boot配置中解决此问题?

编辑:可能的Java客户端代码发出请求:

public String process(String question) {

QueryInfo queryInfo = getQueryInfo(question);

ObjectMapper mapper = new ObjectMapper();

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

String jsonResult = null;

try {

String jsonStr = mapper.writeValueAsString(queryInfo);

String urlStr = Parameters.getQeWebserviceUrl() + URLEncoder.encode(jsonStr, "UTF-8");

URL url = new URL(urlStr);

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));

jsonResult = in.readLine();

in.close();

} catch (Exception jpe) {

jpe.printStackTrace();

}

return jsonResult

}

回答:

如果没有从客户端进行编码-如果在Servlet中处理请求之前遵循以下任何策略通过编码,您仍然可以实现此目标:

  • 使用Spring预处理器bean预处理控制器端点请求
  • 使用Spring AspectJ预处理控制器端点请求
  • 使用Spring Servlet过滤器预处理控制器端点请求

使用以上任何一种横切策略,您都可以对请求URL进行编码,然后传递回端点。

例如,以下是使用过滤器的一种实现。如果需要更好的性能,可以在此进行一些缓存。

@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-boot中的URI编码问题? 的全部内容, 来源链接: utcz.com/qa/428581.html

回到顶部