You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat项目中通过Ajax JSON传递JS Map至Servlet的内容获取问题

解决Tomcat Servlet接收JavaScript Map的问题

嘿,我碰到过类似的坑,这就帮你捋清楚问题出在哪以及怎么解决!

问题根源

你之前用request.getParameterValues("datos")拿不到实际内容,是因为这个方法是用来获取**表单格式(application/x-www-form-urlencoded)**的请求参数,而你发送的是JSON格式的数据——要么是请求体里的纯JSON,要么是表单参数里的JSON字符串,但getParameterValues返回的是字符串数组,直接打印就会显示对象引用([Ljava.lang.String@xxx),根本没解析JSON内容。

正确解决方案步骤

1. 前端修正:正确转换Map并发送JSON

首先,JavaScript的Map直接用JSON.stringify会转成空对象{},所以得先把Map转成普通对象,再转JSON字符串。同时要设置正确的请求头,告诉后端这是JSON数据:

// 假设你的ticket Map结构是这样的
const ticket = new Map();
ticket.set('ticket1', { nombre: 'Entrada VIP', precio: 150, cantidad: 1 });
ticket.set('ticket2', { nombre: 'Entrada General', precio: 80, cantidad: 2 });

// 把Map转为普通对象(关键!不然JSON.stringify会得到空对象)
const ticketObj = Object.fromEntries(ticket);
const jsonData = JSON.stringify(ticketObj);

// 发送Ajax请求
$.ajax({
    url: '/TuServletPath', // 替换成你的Servlet路径
    type: 'POST',
    contentType: 'application/json', // 必须设置这个请求头
    data: jsonData, // 直接把JSON字符串作为请求体发送
    success: function(res) {
        console.log("数据发送成功!", res);
    },
    error: function(xhr, err) {
        console.error("发送失败:", err);
    }
});

2. 后端Servlet:读取并解析JSON

后端需要读取请求体里的JSON字符串,然后用JSON解析库(比如Gson或Jackson)把它转成Java的Map或者自定义对象。这里以Gson为例:

第一步:添加Gson依赖(Maven项目)

如果是Maven,在pom.xml里加:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version> <!-- 用最新稳定版 -->
</dependency>
第二步:Servlet代码修改
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Map;

@WebServlet("/TuServletPath")
public class TicketServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 读取请求体中的JSON字符串
        BufferedReader reader = request.getReader();
        StringBuilder jsonBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            jsonBuilder.append(line);
        }
        String jsonStr = jsonBuilder.toString();

        // 2. 用Gson解析JSON为Java的Map<String, Ticket>
        Gson gson = new Gson();
        // 这里用TypeToken来指定泛型类型,避免类型擦除问题
        Map<String, Ticket> ticketMap = gson.fromJson(
            jsonStr,
            new TypeToken<Map<String, Ticket>>() {}.getType()
        );

        // 3. 现在可以正常遍历Map获取内容了!
        for (Map.Entry<String, Ticket> entry : ticketMap.entrySet()) {
            String ticketId = entry.getKey();
            Ticket ticket = entry.getValue();
            System.out.println("Ticket ID: " + ticketId);
            System.out.println("Nombre: " + ticket.getNombre());
            System.out.println("Precio: " + ticket.getPrecio());
            System.out.println("Cantidad: " + ticket.getCantidad());
        }

        // 给前端返回响应
        response.setContentType("application/json");
        response.getWriter().write("{\"status\":\"success\",\"message\":\"数据接收完成\"}");
    }

    // 自定义Ticket类,用来映射JSON中的对象结构
    static class Ticket {
        private String nombre;
        private double precio;
        private int cantidad;

        // Gson需要无参构造函数,必须写!
        public Ticket() {}

        // Getter和Setter方法
        public String getNombre() { return nombre; }
        public void setNombre(String nombre) { this.nombre = nombre; }
        public double getPrecio() { return precio; }
        public void setPrecio(double precio) { this.precio = precio; }
        public int getCantidad() { return cantidad; }
        public void setCantidad(int cantidad) { this.cantidad = cantidad; }
    }
}

备选方案:如果坚持用表单参数传递JSON

如果你不想改请求格式,还是把JSON作为表单参数datos发送,那前端可以这样写:

$.ajax({
    url: '/TuServletPath',
    type: 'POST',
    data: { datos: jsonData }, // 把JSON字符串作为表单参数传递
    success: function(res) { ... }
});

后端就不用读请求体了,直接拿参数再解析:

String jsonStr = request.getParameter("datos");
// 后面的解析步骤和上面一样...

关键注意点

  • 不要直接JSON.stringify JavaScript的Map,必须转成普通对象(Object.fromEntries(ticket))
  • 后端解析JSON时,必须用泛型类型(比如TypeToken)来避免Java的类型擦除问题
  • 确保添加了正确的JSON解析库依赖(Gson或Jackson都可以,选一个你熟悉的)

内容的提问来源于stack exchange,提问作者Abraham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:53:35