Angular服务请求无法到达Java Servlet,求排查指引
日志服务请求无法到达Java Servlet的排查求助
我们团队正在用Angular 16.1.8重构前端,后端基于Open JDK 1.8的Java服务。我需要实现一个Angular日志类,将GUI日志信息传到后端,由Java Servlet接收后通过log4j写入文件。目前遇到的问题是:日志服务的POST请求完全无法到达Servlet,调试时Servlet内没有任何代码执行,但调用日志服务前的流程都正常,且其他同类服务请求能正常抵达对应Servlet。
前端Angular代码
import { Injectable } from '@angular/core'; import { WebServiceClient } from './web.service.client'; @Injectable({ providedIn: 'root' }) export class LogService { constructor(private departureService : WebServiceClient) { } public logToServer(severity : string, message : string) { // 出于安全考虑用POST而非GET,GET会被WebInspect这类安全测试工具标记 return this.departureService.post( "http://localhost:8080/departures" , '/application-log' , { "applicationName" : "Departure-ui", "dateTime" : new Date(), "severity" : severity, "message" : message } , "json"); } }
后端Java Servlet代码
package gov.faa.infra.ifp.web.portlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import gov.faa.infra.ifp.bo.IfpAccessBo.ModeType; import gov.faa.infra.ifp.domain.ResponseMessage.Importance; import gov.faa.infra.ifp.util.IfpSession; import gov.faa.infra.ifp.util.JsonUtils; @WebServlet("/application-log") public class LogServlet extends BaseServiceServlet { private static final long serialVersionUID = 1L; private static final Logger logger = null; @Override protected void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); throw new ServletException("GET method is not supported"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { long start = System.currentTimeMillis(); int transactionHashCode = -1; String parameter = null; Boolean serviceIsValid = null; int status = HttpServletResponse.SC_OK; String statusMessage = null; Log logInput = null; String severity = null; String logMessage = null; try { transactionHashCode = IfpSession.getSession().beginReadOnlyTransaction(); if(this.verifyAccess(ModeType.QueryFlightProcedure, request)) { logInput = JsonUtils.hydrateObject( (parameter = this.readInputAsString(request)) , Log.class); if (StringUtils.isNotEmpty(logInput.getMessage())) { logMessage = ""; if (StringUtils.isNotEmpty(logInput.getDateTime())) logMessage = logMessage + logInput.getDateTime(); if (StringUtils.isNotEmpty(logInput.getApplicationName())) logMessage = logMessage + logInput.getApplicationName(); if (StringUtils.isNotEmpty(logInput.getSeverity())) logMessage = logMessage + logInput.getSeverity(); if (StringUtils.isNotEmpty(logInput.getMessage())) logMessage = logMessage + logInput.getMessage(); severity = logInput.getSeverity(); switch (severity) { case "success": logger.trace(logMessage); break; case "info": logger.info(logMessage); break; case "warning": logger.warn(logMessage); break; case "error": logger.error(logMessage); break; } } else { IfpSession.getSession().addMessage(Importance.Failure, "empty log message", null); status = HttpServletResponse.SC_BAD_REQUEST; } } else status = HttpServletResponse.SC_UNAUTHORIZED; IfpSession.getSession().addMessage(Importance.Failure, "unauthorized access", null); } catch(Exception exception) { this.ifpSessionResponseWithExceptionAndRollback( response, null, transactionHashCode , "unable to write log" + (statusMessage == null ? "" : " while " + statusMessage) , exception , new Object[] { serviceIsValid, parameter }); } finally { IfpSession.getSession().rollbackTransaction(transactionHashCode); this.logTiming("completed LogServlet.doPost", start); } } }
排查思路
- 抓包确认请求状态:用浏览器开发者工具(Network面板)或Postman直接发起请求,检查请求的URL、方法、参数、响应状态码。重点排查是否存在跨域(CORS)问题,或4xx/5xx错误。
- 验证URL拼接正确性:确认Angular中
post方法拼接后的最终URL是http://localhost:8080/departures/application-log,和Servlet的@WebServlet("/application-log")上下文路径是否匹配。 - 检查WebServiceClient的POST实现:其他服务可用不代表该方法适配所有场景,确认请求头(如Content-Type是否为application/json)、参数序列化是否正确,是否存在请求被吞的情况。
- 确认Servlet是否被加载:查看服务器启动日志,搜索
LogServlet或/application-log确认注册状态;也可在Servlet构造方法中加打印日志,验证是否被容器正确加载。 - 排查权限拦截逻辑:代码中存在
verifyAccess权限校验,检查当前请求是否通过验证,是否在权限阶段就被拦截返回401,但前端未处理该响应导致误以为请求未到达Servlet。 - 检查请求体读取逻辑:Servlet中用
readInputAsString(request)读取请求体,确认该方法是否正确处理JSON数据,是否因读取失败抛出未捕获的异常(如请求体为空、编码不匹配)。 - 排查全局过滤器/拦截器:检查后端是否有全局过滤器对
/application-log路径做特殊处理(如限流、黑名单),导致请求被拦截。 - 修复Logger空指针问题:代码中
logger = null会导致空指针异常,后续需用LoggerFactory.getLogger(LogServlet.class)初始化Logger,避免请求到达后报错。
内容的提问来源于stack exchange,提问作者lxiscas
相关产品推荐
相关产品推荐

