Могу ли я иметь 2 разных пути для 1 класса в Rest Api? [Дубликат]

Каждый раз, когда вы получаете ...

"Warning: mysqli_fetch_object () ожидает, что параметр 1 будет mysqli_result, boolean задан«

... это, вероятно, из-за проблемы с вашим запросом. prepare() или query() могут возвращать FALSE (логическое), но это общее сообщение об отказе не оставляет вас в стороне от подсказок. Как вы узнаете, что не так с вашим запросом? Вы задаете !

Прежде всего убедитесь, что сообщения об ошибках включены и видны: добавьте эти две строки в начало файла (ов) сразу после открытия <?php:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Если ваше сообщение об ошибках установлено в php.ini, вам не придется беспокоиться об этом. Просто убедитесь, что вы обрабатываете ошибки изящно и никогда не раскрываете истинные причины каких-либо проблем для ваших пользователей. Выявление истинной причины для общественности может быть приглашением на золото с гравировкой для тех, кто хочет нанести вред вашим сайтам и серверам. Если вы не хотите отправлять ошибки в браузер, вы всегда можете следить за журналами ошибок веб-сервера. Расположение журналов будет варьироваться от сервера к серверу, например, на Ubuntu журнал ошибок обычно находится в /var/log/apache2/error.log. Если вы изучаете журналы ошибок в среде Linux, вы можете использовать tail -f /path/to/log в окне консоли, чтобы видеть ошибки, когда они происходят в режиме реального времени .... или как вы их делаете.

Как только вы 'squared away на стандартном сообщении об ошибках, добавляющем проверку ошибок в вашем соединении с базой данных, и запросы дадут вам гораздо более подробную информацию о проблемах. Посмотрите на этот пример, где имя столбца неверно. Во-первых, код, возвращающий роковое сообщение об ошибке:

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
$query = $mysqli->prepare($sql)); // assuming $mysqli is the connection
$query->bind_param('s', $definition);
$query->execute();

Ошибка является общей и не очень помогает вам в решении того, что происходит.

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

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection
    $query->bind_param('s', $definition);
    $query->execute();
    // any additional code you need would go here.
} else {
    $error = $mysqli->errno . ' ' . $mysqli->error;
    echo $error; // 1054 Unknown column 'foo' in 'field list'
}

Если что-то не так, вы можете выплюнуть сообщение об ошибке, которое приведет вас к проблеме , В этом случае в таблице нет столбца foo, решение проблемы тривиально.

Если вы выберете, вы можете включить эту проверку в функцию или класс и расширить ее, обработав ошибки изящно, как упомянутых ранее.

24
задан ROMANIA_engineer 28 December 2015 в 16:50
поделиться

3 ответа

Вы не можете иметь mutliple @Path аннотации по одному методу. Это приводит к синтаксической ошибке «дублирования аннотации».

Однако существует несколько способов эффективного сопоставления двух путей к методу.

Регулярные выражения в аннотации @Path

Аннотации @Path в JAX-RS принимают параметры, значения которых могут быть ограничены с помощью регулярных выражений.

Эта аннотация :

@Path("a/{parameter: path1|path2}")

позволит получить доступ к методу запросов как для /a/path1, так и для /a/path2. Если вам нужно работать с подпакетами, выполните слэши: {a:path1\\/subPath1|path2\\/subPath2}

Выполнение ответов с кодом статуса перенаправления

В качестве альтернативы вы можете настроить перенаправление. Вот как это сделать в Джерси (эталонная реализация JAX-RS), путем определения другого субресурса. Это просто пример, если вы предпочитаете другой способ обработки перенаправления, не стесняйтесь использовать его.

@Path("basepath")
public class YourBaseResource {

  //this gets injected after the class is instantiated by Jersey    
  @Context
  UriInfo uriInfo; 

  @Path("a/b")
  @GET
  public Responce method1(){
    return Response.ok("blah blah").build();
  }

  @Path("a/b/c")
  @GET
  public Response method2(){
    UriBuilder addressBuilder = uriInfo.getBaseUriBuilder();
    addressBuilder.path("a/b");
    return Response.seeOther(addressBuilder.build()).build();
  }

}

Использование фильтра сервлета для перезаписи URL-адресов

Если вы часто требуется такая функциональность, я предлагаю перехватить входящие запросы с использованием фильтра сервлета и переписать пути «на лету». Это должно помочь вам сохранить все перенаправления в одном месте. В идеале вы можете использовать готовую библиотеку. UrlRewriteFilter может сделать трюк, если у вас все в порядке с лицензией BSD (подробности см. на сайте своего кодового сайта Google).

Другой вариант - обработать это с помощью прокси-сервер, настроенный перед вашим Java-приложением. Вы можете настроить сервер Apache, чтобы предлагать базовые правила кэширования и перезаписи без усложнения кода Java.

38
ответ дан divideByZero 25 August 2018 в 21:57
поделиться

Как объяснено в ответе Тома , вы не можете использовать более одного аннотации @Path для одного метода, потому что во время компиляции вы будете работать error: duplicate annotation.

Я думаю, что самый простой способ обойти это - использовать перегрузку метода:

@Path("{foo}")
public Response rest(@PathParam("foo") final String foo) {
    return this.rest(foo, "");
}

@Path("{foo}/{bar}")
public Response rest(@PathParam("foo") final String foo,
                     @PathParam("bar") final String bar) {
    return Response.ok(foo + " " + bar).build();
}

Вы также можете использовать более разные имена методов, если вы столкнетесь с тем, что несколько перегруженных методов имеют подпись.

11
ответ дан Community 25 August 2018 в 21:57
поделиться

Другое решение для вашего конкретного примера:

Предположим, что:

  • /a для класса ресурсов
  • /b/c и /b - пути для методов

, поскольку полный путь выглядит следующим образом:

<protocol><host><port><app><url-pattern><resource-path><method-path>.

Используйте необязательный параметр

@Path("/b{c : (/c)?}")
public Response searchNames(@PathParam("c") String val) {
    ...
}

Пример выше работает для всех примеров, таких как:

  • /b
  • /b/
  • /b/c
  • /b/c/

, но если c предоставлен, val - /c (перед ним есть /).

Если вы хотите решить проблему выше (чтобы избежать разбора Java), вам нужно что-то более сложное:

@Path("/b{slash : (/)?}{c:((?<=/).*)?}")

, который вернет только c (не /c) для 3-я маркерная точка, но для четвертой маркерной точки она вернет c/, которая должна быть проанализирована на Java.

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

5
ответ дан ROMANIA_engineer 25 August 2018 в 21:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: