2017-02-09 9 views
1

Я разрабатываю API REST с JAX-RS. Я последовал за this tutorial, и теперь я отлично использую приложение. Но у меня проблема с URL Paths. Grizzly автоматически создан BASE_URI в основном методе, где я addded свой собственный путь:Grizzly JAX-RS НЕ возвращает 400 Bad Request

// Base URI the Grizzly HTTP server will listen on 
public static final String BASE_URI = "http://localhost:8080/app/api/1.0 

Если пользователь вводит base_uri неправильно, например, "http://localhost:8080/ap/ap/1.0/path/to/myResourse/123" Grizzly возвращает

Not Found 
Resource identified by path '/app/api/1.0/whatever/the/user/entered, does not exist. 
Grizzly 2.3.28. 

Проблема в том, что если пользователь вводит BASE_URI правильно, но входит в мой путь ресурсов неправильно, Grizzly не показывает, что «Ресурс не найден» сообщение, а просто показывает пустой экран с HTTP-заголовком 404.

Итак, как я могу отобразить 400 Bad Request, который сообщает пользователю, что он сделал запрос на недопустимый URL? И как я могу изменить сообщение об ошибке по умолчанию, которое предоставляет Grizzly?

Я попытался найти созданные сообщения об ошибках, включая ExceptionMappers, но я думаю, что это не то, что я ищу. Одним из решений, о котором я могу думать, является создание нового класса для каждого / в пути URL, но это не очень элегантный подход ...?

Ниже мой класс ресурсов, который подключается к другому REST API, откуда он получает ресурсы, которые я тогда отображения в моем API

@Path("/path/to/myResourse") 
public class ResourceService { 

    @GET 
    @Path("{id}") 
    @Produces(MediaType.APPLICATION_JSON + "; charset=UTF-8") 
    public Response getBuildingSite(@PathParam("id") String id) throws Exception { 

    StringBuilder sb = new StringBuilder(); 
    sb.append("https://www.exmaple.com/rest/api/resources"); 
    sb.append(id); 
    sb.append(".xml"); 
    String url = sb.toString(); 

    try { 
     Resource resource = Connector.fetch(Resource.class, url); 
     return JSONMapper.asOkJsonResponse(resource); 
    } catch (Exception e) { 
     return JSONMapper.asErrorJsonResponse(
     new ErrorResponse(404,"Resource '" + id + "' not found")); 
    } 
    } 
} 

Мой pom.xml файл

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 

    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.example.app.exampleApp</groupId> 
    <artifactId>exampleApp</artifactId> 
    <packaging>jar</packaging> 
    <version>1.0-SNAPSHOT</version> 
    <name>exampleApp</name> 

    <dependencyManagement> 
    <dependencies> 
     <dependency> 
     <groupId>org.glassfish.jersey</groupId> 
     <artifactId>jersey-bom</artifactId> 
     <version>${jersey.version}</version> 
     <type>pom</type> 
     <scope>import</scope> 
     </dependency> 
    </dependencies> 
    </dependencyManagement> 

    <dependencies> 
    <dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-grizzly2-http</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-json-jackson</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.9</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.mariadb.jdbc</groupId> 
     <artifactId>mariadb-java-client</artifactId> 
     <version>1.5.7</version> 
    </dependency> 
    </dependencies> 

    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>2.5.1</version> 
     <inherited>true</inherited> 
     <configuration> 
      <source>1.8</source> 
      <target>1.8</target> 
     </configuration> 
     </plugin> 
     <plugin> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>exec-maven-plugin</artifactId> 
     <version>1.2.1</version> 
     <executions> 
      <execution> 
      <goals> 
       <goal>java</goal> 
      </goals> 
      </execution> 
     </executions> 
     <configuration> 
      <mainClass>com.example.app.exampleApp.Main</mainClass> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 

    <properties> 
    <jersey.version>2.25</jersey.version> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 
</project> 

ответ

0

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

Благодаря peeskillet's answer по адресу derabbink's question, где я нашел эту идею.

Ниже ресурс я создал:

@Path("{any: .*}") 
public class NotFoundService { 

    @GET 
    @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8") 
    public Response getNotFound(@Context UriInfo uriInfo) { 
    // My custom response where I can use uriInfo to tell what went wrong 
    } 
} 

Так что теперь, если пользователь вводит путь, который имеет правильные БАЗЫ URI, но неверный путь ресурса, например, "http://localhost:8080/app/api/1.0"/invalid/path он вернет все, что я положил в свой обычай Response.