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

Java EE中HttpServlet doPut发送PUT请求抛出异常求助

问题根因

你遇到的Servlet.service() for servlet [VariablesCalculator] in context with path [] threw exception是Servlet容器抛出的通用异常,本质是请求处理链路中出现了未捕获的异常,常见触发原因分两类:

  • 客户端侧:请求构造不合法,包括URI格式不符合要求、请求实体未指定编码/Content-Type、传入的变量名不符合「单个小写拉丁字符」的规则
  • 服务端侧:Servlet路径映射配置错误、路径参数提取逻辑有bug、请求体读取失败、业务逻辑未做异常捕获,导致异常直接抛到Servlet容器层
可行解决方案

客户端请求修复(以Apache HttpClient 4.x为例)

你之前的代码缺失了请求初始化、编码配置等关键步骤,参考如下可运行的代码构造请求:

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.nio.charset.StandardCharsets;

public class CalcClient {
    public static void main(String[] args) throws Exception {
        // 变量名严格遵守规则:单个a-z范围的小写拉丁字符
        String varName = "x";
        // 要设置的变量值
        String varValue = "1024";
        // 拼接符合规则的全路径请求URI,替换为实际的服务地址和端口
        HttpPut httpPut = new HttpPut(String.format("http://localhost:8080/calc/%s", varName));

        // 构造请求实体,必须显式指定UTF-8编码,避免乱码
        StringEntity entity = new StringEntity(varValue, StandardCharsets.UTF_8);
        // 纯文本值设置对应Content-Type,和服务端读取逻辑匹配
        entity.setContentType("text/plain; charset=utf-8");
        httpPut.setEntity(entity);

        // 执行请求并处理响应
        try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
            HttpResponse response = httpclient.execute(httpPut);
            int statusCode = response.getStatusLine().getStatusCode();
            String respContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            System.out.println("响应状态码:" + statusCode);
            System.out.println("响应内容:" + respContent);
        }
    }
}

客户端注意事项:

  • 变量名必须严格校验,禁止传入多字符、大写字母、数字或特殊符号
  • 禁止使用无参的StringEntity构造方法,必须显式指定编码,否则会使用默认ISO-8859-1编码,服务端解析会乱码报错
  • Content-Type要和服务端的解析逻辑匹配,如果传JSON格式值就设置为application/json; charset=utf-8
  • 实际调用时URI要写全路径,不要写相对路径

服务端doPut逻辑修复

参考如下代码修复Servlet配置和处理逻辑,避免未捕获异常抛出:

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.nio.charset.StandardCharsets;
import java.util.regex.Pattern;

// 配置Servlet映射,匹配所有/calc/开头的请求
@WebServlet(urlPatterns = "/calc/*")
public class VariablesCalculator extends HttpServlet {
    // 校验变量名规则:路径最后一段必须是单个小写拉丁字母
    private static final Pattern VALID_VAR_PATTERN = Pattern.compile("^/([a-z])$");

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            // 提取路径参数
            String pathSeg = req.getPathInfo();
            // 校验变量名合法性
            if (pathSeg == null || !VALID_VAR_PATTERN.matcher(pathSeg).matches()) {
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "变量名非法,必须为单个小写拉丁字符");
                return;
            }
            String varName = VALID_VAR_PATTERN.matcher(pathSeg).group(1);

            // 读取请求体中的变量值
            StringBuilder valueBuilder = new StringBuilder();
            try (BufferedReader reader = req.getReader()) {
                String line;
                while ((line = reader.readLine()) != null) {
                    valueBuilder.append(line);
                }
            }
            String varValue = valueBuilder.toString().trim();

            // 执行业务逻辑,示例为存入全局上下文,替换为你自己的存储逻辑即可
            getServletContext().setAttribute(varName, varValue);

            // 返回成功响应
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.setContentType("text/plain; charset=utf-8");
            resp.getWriter().write("变量设置成功," + varName + " = " + varValue);
        } catch (Exception e) {
            // 捕获所有业务异常,避免抛到容器层触发通用错误
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "请求处理失败:" + e.getMessage());
        }
    }
}

服务端注意事项:

  • 如果使用web.xml配置Servlet,需确保<url-pattern>配置为/calc/*,否则请求无法匹配到对应Servlet
  • 不要在读取请求体之前调用getParameter()、getParameterMap()等方法,会导致请求体流被提前消费,后续无法读取
  • 所有业务逻辑必须包裹在异常捕获中,不要把数据库操作、参数解析等环节的异常直接抛出
  • 如果请求体是JSON格式,替换对应的Content-Type配置,使用JSON工具解析请求体即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:48:37