关于rest:泽西岛客户端不遵循重定向

Jersey client doesn't follow redirects

我的"用户"资源定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Path("/api/users")
public class UserResource {

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addUser(User userInfo) throws Exception {
                String userId;
        User existing = ... // Look for existing user by mail
        if (existing != null) {
            userId = existing.id;
        } else {
            userId = ... // create user
        }
        // Redirect to the user page:
        URI uri = URI.create("/api/users/" + userId);
        ResponseBuilder builder = existing == null ? Response.created(uri) : Response.seeOther(uri);
        return builder.build();
    }

    @Path("{id}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public User getUserById(@PathParam("id") String id) {
        return ... // Find and return the user object
    }
}

然后,我正在尝试使用 Jersey 客户端测试用户创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
clientConfig.getFeatures().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, Boolean.TRUE);
Client client = Client.create(clientConfig);
client.addFilter(new LoggingFilter(System.out));

User userInfo = UserInfo();
userInfo.email ="test";
userInfo.password ="test";
client.resource("http://localhost:8080/api/users")
    .accept(MediaType.APPLICATION_JSON)
    .type(MediaType.APPLICATION_JSON)
    .post(User.class, userInfo);

我得到以下异常:

SEVERE: A message body reader for Java class com.colabo.model.User,
and Java type class com.colabo.model.User, and MIME media type
text/html; charset=iso-8859-1 was not found

这是 HTTP 请求的踪迹:

1
2
3
4
5
6
7
8
9
10
11
12
1 * Client out-bound request
1 > POST http://localhost:8080/api/users
1 > Accept: application/json
1 > Content-Type: application/json
{"id":null,"email":"test","password":"test"}
1 * Client in-bound response
1 < 201
1 < Date: Tue, 03 Jul 2012 06:12:38 GMT
1 < Content-Length: 0
1 < Location: /api/users/4ff28d5666d75365de4515af
1 < Content-Type: text/html; charset=iso-8859-1
1 <

在这种情况下,Jersey 客户端是否应该自动遵循重定向,并从第二个请求中正确解组并返回 Json 对象?

谢谢,
迈克尔


我遇到了同样的问题,并通过以下客户端过滤器解决了它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package YourPackageName;


import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;

public class RedirectFilterWorkAround implements ClientResponseFilter {
    @Override
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
        if (responseContext.getStatusInfo().getFamily() != Response.Status.Family.REDIRECTION)
            return;

        Response resp = requestContext.getClient().target(responseContext.getLocation()).request().method(requestContext.getMethod());

        responseContext.setEntityStream((InputStream) resp.getEntity());
        responseContext.setStatusInfo(resp.getStatusInfo());
        responseContext.setStatus(resp.getStatus());
    }
}

现在在您创建客户端的其他类中

1
Client client = ClientBuilder.newClient();

将此过滤器类应用为

1
client.register(RedirectFilterWorkAround.class);

这适用于 Jersey 2.x
在 SO 上找到这些指针:p


跟随重定向意味着跟随 30x 状态代码重定向。您所拥有的是 201 响应,这不是重定向。如果返回 201,您可以编写一个将跟随位置标头的 ClientFilter。