Можно ли поместить переменные в путь к ресурсу в сервлете sling?

Мы пытаемся предоставить чистую структуру URI для внешних конечных точек, чтобы получать информацию json из CQ5.

Например, если вы хотите получить информацию о конкретной истории пользователей (при условии, что у вас есть разрешения и т. д.), в идеале мы хотели бы, чтобы конечная точка могла делать следующее:

/bin/api/пользователь/abc123/телефон/555-клондайк-5/history.json

В URI мы бы указали /bin/api/user/{username}/phone/{phoneNumber}/history.json, чтобы очень легко использовать диспетчер для аннулирования изменений кэширования и т. д. без аннулирования большого количества кэшированной информации. .

Мы хотели бы использовать sling-сервлет для обработки запроса, однако я не знаю, как поместить переменные в путь.

Было бы здорово, если бы было что-то вроде @PathParam от JaxRS для добавления к переменной пути sling, но я подозреваю, что это недоступно.

Другой подход, который мы имели в виду, заключался в использовании селектора для распознавания, когда мы обращаемся к API, и, таким образом, могли бы вернуть все, что мы хотели, из пути, но это потребовало бы отдельного сервлета sling для обработки всех запросов, и поэтому Я недоволен этим подходом, так как он склеивает воедино много несвязанного кода.

Любая помощь в этом будет оценена по достоинству.


ОБНОВИТЬ:

Если бы мы использовали OptingServlet, а затем поместили бы некоторую логику в функцию accepts, мы могли бы сложить ряд sling-сервлетов и принять решения о принятии из пути с регулярным выражением.

Затем во время выполнения сам путь может быть проанализирован на наличие переменных.


person Bayani Portier    schedule 08.01.2014    source источник


Ответы (5)


Теперь можно интегрировать jersy(JAX-RS) с CQ. Мы можем создать примитивный прототип, чтобы поздороваться с миром.

https://github.com/hstaudacher/osgi-jax-rs-connector

При этом мы можем использовать @PathParam для сопоставления запросов.

Спасибо и С уважением, Сан

person kallada    schedule 14.09.2015

Если данные, которые вы предоставляете, поступают из репозитория JCR, лучше всего структурировать их именно так, как вы хотите, чтобы URL-адреса были, это рекомендуемый способ работы с Sling.

Если данные являются внешними, вы можете создать собственный Sling ResourceProvider, который вы монтируете по пути /bin/api/user и получаете или создаете соответствующие данные на основе остальной части пути.

Простым примером этого является PlanetsResourceProvider набора тестов Sling, см. http://svn.apache.org/repos/asf/sling/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/resourceprovider/

Документы ресурсов Sling по адресу https://sling.apache.org/documentation/the-sling-engine/resources.html документирует общий механизм разрешения ресурсов.

person Bertrand Delacretaz    schedule 09.01.2014

Не существует прямого способа создания таких динамических путей. Вы можете зарегистрировать сервлет под /bin/api/user.json и указать остальную часть пути как суффикс:

/bin/api/user.json/abc123/phone/555-klondike-5/history
^                 ^
|                 |
servlet path      suffix starts here

то вы можете разобрать суффикс вручную:

@SlingServlet(paths = "/bin/api/user", extensions = "json")
public class UserServlet extends SlingSafeMethodsServlet {
    public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
        String suffix = request.getRequestPathInfo().getSuffix();
        String[] split = StringUtils.split(suffix, '/');
        // parse split path and check if the path is valid
        // if path is not valid, send 404:
        // response.sendError(HttpURLConnection.HTTP_NOT_FOUND);
    }
}
person Tomek Rękawek    schedule 08.01.2014
comment
Привет, Томек, спасибо за ответ. К сожалению, наши требования довольно стабильны, поскольку мы имеем дело с устаревшими приложениями, которые мы стараемся не переписывать. - person Bayani Portier; 29.01.2014
comment
@Tomek Rękawek У меня есть сомнения, что это то, что вы предлагаете в качестве альтернативы веб-службе REST в CQ5, предположим, что какой-то инструмент внешнего приложения хочет получить доступ через REST, и мы предоставляем этот сервлет, и этот инструмент пытается создать WADL для этого RESTWebservice (наш сервлет), то он терпит неудачу. Итак, знаете ли вы, как мы можем реализовать точный веб-сервис для отдыха, чтобы даже генерация WADL для этого URL-адреса REST завершалась успешно? - person samir; 06.11.2015

RESTful подход к этому заключается в том, чтобы хранить информацию в структуре, которую вы хотите использовать. то есть /content/user/abc123/phone/555-klondike-5/history/ будет содержать все узлы истории для этого пути.

В этом использовании. вы можете получить готовый ответ json, просто позвонив

/content/user/abc123/phone/555-klondike-5/history.json

Или, если вам нужно что-то в определенном формате json, вы можете использовать разрешение ресурса sling для использования пользовательского ответа json.

person JE Bailey    schedule 08.01.2014
comment
К сожалению, это невозможно, так как мы имеем дело с устаревшими приложениями, которые помещают идентификатор пользователя в начало запроса покоя. Мы не можем хранить данные в таком графике. - person Bayani Portier; 29.01.2014

Рад поделиться этим! Я работал ~ неделю, решая это, наконец, получил лучший ответ.

Во-первых: попробуйте использовать Джерси

osgi-jax-rs-connector, предложенный kallada, лучше всего, но я не смог заставить его работать на Sling 8. Я потратил целый день на попытки, все, что мне нужно показать, это жуткий класс, не найденный, ошибки и проблемы с зависимостями.

Решение: ResourceProvider

Ссылка Бертрана предназначена только для Sling 9, который еще не выпущен. Итак, вот как вы это делаете в Sling 8 и старше!

Два файла:

  • ResourceProvider
  • Сервлет

Провайдер ресурсов

Целью этого является только прослушивание всех запросов в /service, а затем создание «ресурса» по этому виртуальному пути, который фактически не существует в JCR.

@Component
@Service(value=ResourceProvider.class)
@Properties({
        @Property(name = ResourceProvider.ROOTS, value = "service/image"),
        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
})
public class ImageResourceProvider implements ResourceProvider  {

@Override
public Resource getResource(ResourceResolver resourceResolver, String path) {

    AbstractResource abstractResource;
    abstractResource = new AbstractResource() {
        @Override
        public String getResourceType() {
            return TypeServlet.RESOURCE_TYPE;
        }

        @Override
        public String getResourceSuperType() {
            return null;
        }

        @Override
        public String getPath() {
            return path;
        }

        @Override
        public ResourceResolver getResourceResolver() {
            return resourceResolver;
        }

        @Override
        public ResourceMetadata getResourceMetadata() {
            return new ResourceMetadata();
        }
    };

    return abstractResource;
}

@Override
public Resource getResource(ResourceResolver resourceResolver, HttpServletRequest httpServletRequest, String path) {
    return getResource(resourceResolver , path);
}

@Override
public Iterator<Resource> listChildren(Resource resource) {
    return null;
}
}

Сервлет

Теперь вы просто пишете сервлет, который обрабатывает любые ресурсы, поступающие по этому пути, но это достигается путем обработки любых ресурсов с типом ресурса, который создается ResourceProvider, прослушивающим этот путь.

@SlingServlet(
        resourceTypes = TypeServlet.RESOURCE_TYPE,
        methods = {"GET" , "POST"})
public class TypeServlet extends SlingAllMethodsServlet {


    static final String RESOURCE_TYPE = "mycompany/components/service/myservice";

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {

        final String [] pathParts = request.getResource().getPath().split("/");
        final String id = pathParts[pathParts.length-1];
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        try {
            out.print("<html><body>Hello, received this id: " + id + "</body></html>");
        } finally {
             out.close();
        }
    }
}

Очевидно, ваш сервлет будет делать что-то гораздо более умное, например, более разумно обрабатывать строку «путь» и, вероятно, создавать JSON.

person lance.dolan    schedule 31.01.2017