我正在使用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中处理请求之前遵循以下任何策略通过编码,您仍然可以实现此目标:
使用以上任何一种横切策略,您都可以对请求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; } } }