HttpUrlConnection无法获取被调用Java程序抛出的异常信息
问题分析与解决方案
你遇到的核心问题是HttpURLConnection在处理非200响应时,无法通过getInputStream()获取错误响应体,必须使用getErrorStream()来读取异常信息。而Ajax能正常获取是因为浏览器的XMLHttpRequest会自动处理错误响应的内容,不需要手动切换流。
为什么拿不到异常信息?
当Spring Controller抛出未捕获的异常时,服务器会返回500状态码和包含异常信息的响应体,但你的代码里不管响应码是多少都直接调用con.getInputStream()——HttpURLConnection有明确规则:只有响应码在200-299范围内时,getInputStream()才会返回正常响应流;非成功状态码的响应体需要通过getErrorStream()来读取。
解决方案步骤
1. 修改HttpURLConnection调用代码,切换错误流读取
修改你的PoService中的getPo方法,根据响应码选择对应的输入流:
@Path("poService") public class PoService { @Context private UriInfo context; @GET @Path("getPo/{poNo}") @Produces(MediaType.APPLICATION_JSON) public Response getPo(@PathParam("poNo") int poNo ) throws Exception{ String urlStr = AppConstant.WEBOLIS_PATH + "po.htm?getPoForSrnConsReport=true&pono="+poNo ; URL url = new URL(urlStr); HttpURLConnection con = (HttpURLConnection) url.openConnection(); int responseCode = con.getResponseCode(); System.out.println("\nSending 'GET' request to URL : " + url); System.out.println("Response Code : " + responseCode); System.out.println("Response Message : " + con.getResponseMessage()); BufferedReader in; // 根据响应码选择读取的流 if (responseCode >= 200 && responseCode < 300) { in = new BufferedReader(new InputStreamReader(con.getInputStream())); } else { in = new BufferedReader(new InputStreamReader(con.getErrorStream())); } String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); if( responseCode!=200 ){ // 这里就能拿到异常的具体信息了 System.out.println("Error Details: " + response.toString()); // throw new WebolisApiException( responseCode, response.toString()); } return Response.ok( response.toString(), MediaType.APPLICATION_JSON).build(); } }
2. 确保Spring正确返回异常的JSON格式(可选但推荐)
虽然你提到Ajax能拿到异常信息,但为了让Java端更方便解析,建议给Spring添加全局异常处理器,统一返回JSON格式的错误信息:
@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = {RuntimeException.class, Exception.class}) @ResponseBody public ResponseEntity<Map<String, Object>> handleException(Exception ex) { Map<String, Object> errorMap = new HashMap<>(); errorMap.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value()); errorMap.put("message", ex.getMessage()); errorMap.put("timestamp", new Date()); return new ResponseEntity<>(errorMap, HttpStatus.INTERNAL_SERVER_ERROR); } }
这样修改后,你的Java调用端就能读取到结构化的异常信息,而不是可能的HTML错误页面内容。
内容的提问来源于stack exchange,提问作者Dattatray Choudhari
相关产品推荐
相关产品推荐

