JAX-RS Java Jersey返回JSON至JS前端时多余转义反斜杠导致结构无效
多余的转义反斜杠产生于Java后端封装响应的环节,和前端请求逻辑、外部API返回都没有关系:
你的Java接口代码中,将已经完成解析的结构化JSONObject对象调用toString()转为了JSON字符串,再将这个字符串作为zoekopdracht字段的值存入messages响应对象。Jersey的JSON序列化器在将整个messages对象序列化为HTTP响应的JSON内容时,为了保证JSON语法合法,会自动对字符串类型值内部的所有双引号添加反斜杠转义,最终前端拿到的zoekopdracht就成了被转义的字符串,而非预期的嵌套JSON对象。
你之前尝试用replace('\\','')删除反斜杠的方案无法解决问题:一是非全局正则替换只会删除第一个匹配的反斜杠,二是无差别删除反斜杠会破坏JSON内容里合法的转义字符(比如文本中自带的引号、换行符转义),反而会进一步损坏JSON结构。
1. 后端根因修复(推荐)
不要将结构化的JSONObject转为字符串再存入响应对象,直接放入原生对象即可,Jersey序列化时会自动将其处理为正确的嵌套JSON结构,不会产生多余转义。
修改Java接口中的赋值逻辑:
// 原错误写法:将JSONObject转成字符串再存入 messages.put("zoekopdracht", resultaat.toString()); // 修正后:直接放入JSONObject对象,无需调用toString() messages.put("zoekopdracht", resultaat);
另外你的fetchSearchResultAsJson方法存在流资源泄漏风险,建议改用try-with-resources语法自动管理流关闭,无需手动调用close方法:
public JSONObject fetchSearchResultAsJson(String theURL) throws IOException { URL url = new URL(theURL); try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()))) { JSONTokener tokener = new JSONTokener(bufferedReader); return new JSONObject(tokener); } }
修复后前端通过response.json()拿到的响应中,zoekopdracht字段会直接是可直接访问的结构化JSON对象,无需任何额外解析处理。
2. 前端临时兼容方案(仅用于暂时无法修改后端代码的场景)
如果后端暂时无法调整,不要手动替换反斜杠,直接对zoekopdracht字段单独做一次JSON解析即可:
const fetchOptions = { method: 'POST', body: JSON.stringify(jsonRequestBody), headers: { Authorization: `Bearer ${window.sessionStorage.getItem('JWT')}`, Accept: 'application/json', 'Content-Type': 'application/json', }, }; const feedbackSpan = document.getElementById('feedbackSpan'); fetch(`${localhost}restservices/search-advanced-service/`, fetchOptions) .then(async (response) => { if (response.status === 200) { const myJson = await response.json(); // 单独解析被序列化为字符串的嵌套JSON字段 myJson.zoekopdracht = JSON.parse(myJson.zoekopdracht); console.log(myJson); // 后续业务逻辑可直接访问myJson.zoekopdracht下的字段 } if (response.status === 403) { feedbackSpan.innerHTML = '<p>Check of je bent ingelogd!</p>'; } }) .catch((err) => { console.log('Error: ', err); });
内容的提问来源于stack exchange,提问作者Ryan Reddy

