Windchill 12.1通过Java API获取CSRF_NONCE报HTTP 400错误求助
问题:Windchill 12.1 CSRF Token接口Java调用返回HTTP 400,浏览器正常
我尝试通过Java API从Windchill 12.1服务器获取CSRF_NONCE值,但始终返回HTTP 400错误。已尝试两个请求地址:
https://myServer/Windchill//servlet/rest/objects?$select=number&typeId=wt.part.WTParthttps://myServer/Windchill/servlet/odata/v3/PTC/GetCSRFToken()
这两个请求在Firefox浏览器中均可正常执行,但使用以下Java代码调用GetCSRFToken()时失败。另外,使用相同代码调用第一个REST接口能正常获取数据。
尝试的Java代码如下:
URL url = new URL ("https://myServer/Windchill/servlet/odata/v3/PTC/GetCSRFToken()"); HttpURLConnection conn = (HttpURLConnection) obj.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Authorization", "Basic " + authString); //authstring is Base64 encoded conn.connect(); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); conn.disconnect();
请问为何会出现浏览器请求正常但Java代码调用失败的差异?
可能的原因及解决方案
1. 请求头缺失关键字段
浏览器发起请求时会自动携带Accept、User-Agent等默认头,而你的Java代码仅设置了Content-Type和Authorization。Windchill的OData接口可能对请求头有严格校验:
- 缺少
Accept头:服务器无法确定返回格式,触发400错误; - 缺少
User-Agent:部分服务器会拒绝无用户代理标识的请求。
修复方式:添加这两个请求头:
conn.setRequestProperty("Accept", "application/json"); conn.setRequestProperty("User-Agent", "Mozilla/5.0");
2. URL特殊字符未编码
浏览器会自动对URL中的括号()等特殊字符编码,但Java的URL类可能未正确处理,导致服务器解析URL失败。
修复方式:用URI类构建正确的URL:
URI uri = new URI("https", "myServer", "/Windchill/servlet/odata/v3/PTC/GetCSRFToken()", null); URL url = uri.toURL();
3. 未维护会话Cookie
浏览器会自动维护会话Cookie,而Java代码未处理Cookie。Windchill的CSRF接口可能需要先通过会话关联身份,即使使用Basic Auth也可能依赖Cookie。
修复方式:添加Cookie管理逻辑:
CookieManager cookieManager = new CookieManager(); CookieHandler.setDefault(cookieManager); // 先调用任意能返回会话Cookie的Windchill接口,再请求CSRF Token
4. 请求方法或Content-Type不匹配
Windchill的OData GetCSRFToken接口可能要求POST方法,或者GET请求不需要设置Content-Type(因为GET无请求体),你的代码设置的Content-Type: application/json可能不符合服务器预期。
修复方式:去掉Content-Type头,或尝试改为POST请求:
// 移除Content-Type设置 // conn.setRequestProperty("Content-Type", "application/json"); // 或切换请求方法 conn.setRequestMethod("POST");
内容的提问来源于stack exchange,提问作者neshko
相关产品推荐
相关产品推荐

