未找到Java类型消息体写入器(MIME类型application/x-www-form-urlencoded)求助
解决JERSEY REST客户端获取令牌的问题
刚接触JERSEY确实容易踩版本或参数传递的坑,你说之前的方案都不适用,大概率是版本不匹配或者请求格式没对齐服务端要求——我结合你的代码片段,分版本给你补全优化方案:
先明确JERSEY版本(关键!)
很多旧方案用的是JERSEY 1.x的API,但现在大部分新项目用的是2.x,两者的客户端API差异很大,这是最常见的“方案不适用”原因:
- JERSEY 1.x:用
Client.create()创建客户端 - JERSEY 2.x:用
ClientBuilder.newClient()创建客户端
方案1:JERSEY 1.x 完整实现
补全你没写完的代码,同时处理请求、响应和资源释放:
import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.representation.Form; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status; import java.util.HashMap; import java.util.Map; public String getToken() { String urlToken = "http://example.com"; Client client = Client.create(); // 构建请求参数:支持两种常见格式,按需选择 // 方式A:表单格式(application/x-www-form-urlencoded) Form formParams = new Form(); formParams.add("username", "your-actual-username"); formParams.add("password", "your-actual-password"); // 方式B:JSON格式(application/json) // Map<String, String> jsonParams = new HashMap<>(); // jsonParams.put("username", "your-actual-username"); // jsonParams.put("password", "your-actual-password"); // GenericEntity<Map<String, String>> jsonEntity = new GenericEntity<Map<String, String>>(jsonParams) {}; try { // 发送POST请求(这里用表单格式示例,JSON的话替换参数和MediaType即可) ClientResponse response = client.resource(urlToken) .type(MediaType.APPLICATION_FORM_URLENCODED) .post(ClientResponse.class, formParams); // 校验响应状态 if (response.getStatus() == Status.OK.getStatusCode()) { // 解析响应:如果服务端返回JSON对象(如{"token":"xxx"}),可自定义类接收 // TokenResponse tokenResp = response.getEntity(TokenResponse.class); // return tokenResp.getToken(); // 若直接返回令牌字符串,直接读取即可 return response.getEntity(String.class); } else { throw new RuntimeException("获取令牌失败,状态码:" + response.getStatus()); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("请求令牌时发生异常", e); } finally { // 务必关闭客户端释放资源 client.destroy(); } } // 自定义响应类示例(服务端返回JSON对象时用) // class TokenResponse { // private String token; // // getter和setter方法 // }
方案2:JERSEY 2.x 完整实现
2.x的API做了重构,更简洁,注意依赖要换成glassfish的包:
import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.HashMap; import java.util.Map; public String getToken() { String urlToken = "http://example.com"; Client client = ClientBuilder.newClient(); // 同样支持表单或JSON两种参数方式 Form formParams = new Form(); formParams.param("username", "your-actual-username"); formParams.param("password", "your-actual-password"); // JSON方式示例 // Map<String, String> jsonParams = new HashMap<>(); // jsonParams.put("username", "your-actual-username"); // jsonParams.put("password", "your-actual-password"); try { Response response = client.target(urlToken) .request(MediaType.APPLICATION_JSON) // 服务端返回的格式 .post(Entity.form(formParams)); // 表单请求用Entity.form,JSON用Entity.json(jsonParams) if (response.getStatus() == Response.Status.OK.getStatusCode()) { // 解析响应,同样可以用自定义类接收 return response.readEntity(String.class); } else { throw new RuntimeException("令牌请求失败,状态码:" + response.getStatus()); } } catch (Exception e) { throw new RuntimeException("请求令牌异常", e); } finally { client.close(); } }
几个关键注意点(解决“方案不适用”的核心)
- 请求格式对齐:必须和服务端要求的
Content-Type一致,比如服务端要表单就不能传JSON,反之亦然——很多旧方案没强调这点,导致请求被拒绝。 - 依赖正确:Maven依赖要对应版本:
- 1.x:
com.sun.jersey:jersey-client:1.19.4 - 2.x:
org.glassfish.jersey.core:jersey-client:2.41
- 1.x:
- 异常处理:实际项目中可以捕获
ClientHandlerException等特定异常,处理超时、网络错误等场景。
内容的提问来源于stack exchange,提问作者softwareplay
相关产品推荐
相关产品推荐

