Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 到不同资源的Restlet条件路由_Java_Restlet - Fatal编程技术网

Java 到不同资源的Restlet条件路由

Java 到不同资源的Restlet条件路由,java,restlet,Java,Restlet,我有一个POST请求,我想根据正文内容分配给不同的资源 如果正文包含一个非空的令牌:“token”:“1q2w3e4r5t”那么我想将请求路由到TokenedResource,否则路由到非tokenresource 我想使用Filter(@beforeholder)来处理它,但是Filter返回的唯一指示是继续或停止 有什么建议吗 要做到这一点,您需要扩展Restlet路由。后者负责根据计算出的分数确定与特定请求匹配的路由 特别是路由涉及两个需要覆盖的类:Router和templaterrout

我有一个
POST
请求,我想根据正文内容分配给不同的
资源

如果正文包含一个非空的令牌:
“token”:“1q2w3e4r5t”
那么我想将请求路由到
TokenedResource,
否则路由到
非tokenresource

我想使用Filter(
@beforeholder
)来处理它,但是Filter返回的唯一指示是
继续
停止


有什么建议吗

要做到这一点,您需要扩展Restlet路由。后者负责根据计算出的分数确定与特定请求匹配的路由

特别是路由涉及两个需要覆盖的类:
Router
templaterroute
。路由器1负责创建模板路由。如果要提供自定义模板路由,则需要提供自定义路由器。在自定义模板路由中,然后实现自己的路由分数算法

以下是自定义路由器的实现:

public class CustomRouter extends InternalRouter {
    public CustomRouter(Context context) {
        super(context);
        setFinderClass(CustomFinder.class);
    }

    protected TemplateRoute createRoute(String uriPattern,
                Restlet target, int matchingMode) {
        CustomTemplateRoute result = new CustomTemplateRoute(
                                    this, uriPattern, target);

        result.getTemplate().setMatchingMode(matchingMode);
        result.setMatchingQuery(getDefaultMatchingQuery());
        return result;
    }
}
不太容易理解的是,为什么我们需要使用方法
setFinderClass
指定自定义查找程序。Restlet中的finder负责为每个请求实例化一个服务器资源。默认实现(类
Finder
)的问题是您无法访问关联的类(
targetClass
)。如果您需要了解它(似乎是这样),那么您必须提供自己的实现。稍后我们将重点讨论这个问题

使用此类,以下是在应用程序类中附加服务器资源的方法:

@Override
public Restlet createInboundRoot() {
    Router router = new CustomRouter(getContext());

    router.attach("/test", TokenedResource.class);
    router.attach("/test", NonTokenResource.class);

    return router;
}
我们必须把它们放在同一条路上

以下是自定义模板路由的实现:

public class CustomTemplateRoute extends TemplateRoute {
    public CustomTemplateRoute(Restlet next) {
        super(next);
    }

    public CustomTemplateRoute(Router router,
                  String uriTemplate, Restlet next) {
        super(router, uriTemplate, next);
    }

    public CustomTemplateRoute(Router router,
                  Template template, Restlet next) {
        super(router, template, next);
    }

    @Override
    public float score(Request request, Response response) {
        float result = super.score(request, response);
        (...)
        return result;
    }
}
在方法
score
中,如果是类
TokenedResource
的标记请求,我们将增加分数,否则将降低分数。这允许Restlet为正确的案例选择正确的服务器资源

在继续之前,只需提供CustomFinder类的内容:

public class CustomFinder extends Finder {
    private Class<? extends ServerResource> targetClass;

    public CustomFinder() {
        super();
    }

    public CustomFinder(Context context) {
        super(context);
    }

    public CustomFinder(Context context,
            Class<? extends ServerResource> targetClass) {
        super(context, targetClass);
        this.targetClass = targetClass;
    }
}
方法
isTokenedServerResource
检查与路由关联的服务器资源(如果有)是否为类
TokenedResource
。在本例中,我们查看有效负载,以查看它是否实际包含方法为
containsToken
的令牌

下面是方法
isTokenedServerResource
的示例内容:

private boolean isTokenedServerResource() {
    if (getNext() instanceof CustomFinder) {
        CustomFinder finder = (CustomFinder) getNext();
        if (MyServerResource1.class.isAssignableFrom(finder.getTargetClass())) {
            return true;
        }
    }
    return false;
}
以下是方法
containsToken
的示例内容。它假设使用了JSON内容,我们使用Jackson来解析它

private boolean containsToken(Request request) {
    try {
        Representation repr = request.getEntity();
        String content = repr.getText();

        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> jsonContent = objectMapper.readValue(
                                  content, Map.class);

        StringRepresentation sRepr = new StringRepresentation(
                              content, repr.getMediaType());
        request.setEntity(sRepr);

        if (jsonContent.get("token") != null) {
            return true;
        }
    } catch (Exception ex) {
        (...)
    }
    return false;
}
private boolean containsToken(请求){
试一试{
表示repr=request.getEntity();
String content=repr.getText();
ObjectMapper ObjectMapper=新的ObjectMapper();
Map jsonContent=objectMapper.readValue(
内容、地图、类);
StringRepresentation sRepr=新的StringRepresentation(
content,repr.getMediaType());
请求。setEntity(sRepr);
if(jsonContent.get(“令牌”)!=null){
返回true;
}
}捕获(例外情况除外){
(...)
}
返回false;
}
需要注意的一点是,我们需要在请求中再次设置请求实体(我们在这里使用
StringRepresentation
),因为默认情况下,实体内容只能读取一次

希望它能帮助你,
Thierry

谢谢你的回答,我会在一两天内找到它。你可以在这个链接上查看代码。请随时发表您的评论!
private boolean containsToken(Request request) {
    try {
        Representation repr = request.getEntity();
        String content = repr.getText();

        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> jsonContent = objectMapper.readValue(
                                  content, Map.class);

        StringRepresentation sRepr = new StringRepresentation(
                              content, repr.getMediaType());
        request.setEntity(sRepr);

        if (jsonContent.get("token") != null) {
            return true;
        }
    } catch (Exception ex) {
        (...)
    }
    return false;
}