2016-10-04 12 views
6

Tôi đã sau phương pháp GET REST:OffsetDateTime năng suất "Không có nguồn tiêm tìm thấy cho một tham số kiểu javax.ws.rs.core.response công cộng" trong phương thức GET

import java.time.OffsetDateTime; 

import javax.ws.rs.Consumes; 
import javax.ws.rs.DELETE; 
import javax.ws.rs.GET; 
import javax.ws.rs.HeaderParam; 
import javax.ws.rs.POST; 
import javax.ws.rs.PUT; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.Produces; 
import javax.ws.rs.QueryParam; 
import javax.ws.rs.core.Response; 

import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiOperation; 
import io.swagger.annotations.ApiResponse; 
import io.swagger.annotations.ApiResponses; 
import com.product.rest.api.TransactionsApi; 
import com.product.rest.model.Transaction; 

@Path("/transactions") 

@Api(description = "the transactions API") 
@Consumes({ "application/json" }) 
@Produces({ "application/json" }) 
public class TransactionsApiImpl extends TransactionsApi { 

    @GET 

    @Consumes({ "application/json" }) 
    @Produces({ "application/json" }) 
    @ApiOperation(value = "", notes = "Get all transactions", response =  Transaction.class, responseContainer = "List", tags = {}) 
    @ApiResponses(
     value = { @ApiResponse(code = 200, message = "OK", response =  Transaction.class, responseContainer = "List"), 
      @ApiResponse(code = 400, message = "Bad Request", response =  Transaction.class, responseContainer = "List"), 
      @ApiResponse(code = 404, message = "Not Found", response =  Transaction.class, responseContainer = "List"), 
      @ApiResponse(code = 500, message = "Internal Server Error",  response = Transaction.class, responseContainer = "List") }) 
    @Override 
    public Response transactionsGet(
     @HeaderParam("tok") String tok, 
     @QueryParam("param1") Integer param1, 
     @QueryParam("param2") String param2, 
     @QueryParam("param3") OffsetDateTime param3, 
     @QueryParam("param4") OffsetDateTime param4, 
     @QueryParam("param5") Integer param5, 
     @QueryParam("param6") Integer param6, 
     @QueryParam("param7") String param7) { 
     return Response.ok().entity("Success!").build(); 
    } 

Các TransactionsApi là một việc thực hiện tạo sử dụng Swagger Codegen, cũng như lớp mô hình Transaction. Tôi có một số chức năng khác trong lớp này, nhưng bất cứ khi nào tôi rời khỏi GET /transactions chức năng không chú thích, tôi nhận được lỗi sau:

WARN [Thread-1] (ContextHandler.java:2175) - unavailable 
org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization. 

[[FATAL] No injection source found for a parameter of type public javax.ws.rs.core.Response  
com.product.rest.impl.v1.TransactionsApiImpl.transactionsGet(java.lang.String,java.lang.Integer,java.lang.String,java.time.OffsetDateTime,java.time.OffsetDateTime,java.lang.Integer,java.lang.Integer,java.lang.String) at index 3.; source='ResourceMethod{httpMethod=GET, consumedTypes=[application/json], producedTypes=[application/json], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.product.rest.impl.v1.TransactionsApiImpl, handlerConstructors=[[email protected]]}, definitionMethod=public javax.ws.rs.core.Response 

Tất cả các câu hỏi tương tự khác mà tôi đã tìm thấy đã phải làm với MultiPart Data và tập tin tải lên, trong khi tôi thực hiện yêu cầu GET đơn giản. Các chức năng khác cũng sử dụng lớp javax.ws.rs.code.Response không có vấn đề này và máy chủ khởi động bình thường.

Tôi đã nhận thấy rằng sự cố xảy ra bất cứ khi nào lớp OffsetDateTime có trong các tham số (ví dụ: param3param4), nhưng tôi không thể tìm hiểu lý do. Hơn nữa, OffsetDateTime đã được lựa chọn bởi Swagger Codegen và tôi miễn cưỡng thay đổi nó nhìn thấy làm thế nào tôi sẽ phải thay đổi mọi tập tin có nguồn gốc sau đó bất cứ khi nào tôi tái tạo nguồn của tôi.

Có ai có vấn đề này trước với dịch vụ REST và OffsetDateTime không?

Trả lời

7

All other similar questions I have found had to do with MultiPart Data and file uploading

Nó có liên quan. Lỗi này là lỗi chung mà bạn nhận được khi Jersey không thể xác thực mô hình tài nguyên. Một phần của mô hình tài nguyên là các tham số của phương thức. Jersey có một hệ thống để biết những thông số nào nó có thể xử lý và những thông số nào nó sẽ không. Trong trường hợp của bạn, nó không biết cách xử lý OffsetDateTime.

Có aa bộ quy tắc mà bạn cần phải làm theo để có thể sử dụng các loại phi cơ bản như @QueryParam s:

  1. Hãy là một loại nguyên thủy
  2. Có một constructor mà chấp nhận một đối số duy nhất Chuỗi
  3. có một phương pháp tĩnh tên valueOf hoặc fromString chấp nhận một đối số chuỗi đơn (xem, ví dụ, Integer.valueOf(String))
  4. có một thực hiện đăng ký của ParamConverterProvider JAX-RS SPI mở rộng trả về một phiên bản ParamConverter có khả năng chuyển đổi "từ chuỗi" cho loại đó.
  5. Be List<T>, Set<T> hoặc SortedSet<T>, trong đó T thỏa mãn 2, 3 hoặc 4 ở trên. Bộ sưu tập kết quả là chỉ đọc.

Vì vậy, trong trường hợp này là OffsetDateTime, hãy đi xuống danh sách; nó không phải là nguyên thủy; nó không có một hàm tạo String; nó không có static valueOf hoặc fromString

Vì vậy, về cơ bản, tùy chọn còn lại là triển khai ParamConverter/ParamConverterProvider cho nó. Thiết lập cơ bản trông giống như

@Provider 
public class OffsetDateTimeProvider implements ParamConverterProvider { 

    @Override 
    public <T> ParamConverter<T> getConverter(Class<T> clazz, Type type, Annotation[] annotations) { 
     if (clazz.getName().equals(OffsetDateTime.class.getName())) { 

      return new ParamConverter<T>() { 

       @SuppressWarnings("unchecked") 
       @Override 
       public T fromString(String value) { 
        OffsetDateTime time = ... 
        return (T) time; 
       } 

       @Override 
       public String toString(T time) { 
        return ...; 
       } 
      }; 
     } 
     return null; 
    } 
} 

Về cơ bản, Jersey sẽ vượt qua cho bạn những giá trị String của các tham số truy vấn, và đó là công việc của bạn để tạo ra nó và gửi lại.

Sau đó, chỉ cần đăng ký OffsetDateTimeProvider bằng ứng dụng. Nếu bạn đang sử dụng quét gói, nó sẽ được chọn và đăng ký tự động từ chú thích @Provider.

Tôi không sử dụng Swagger, vì vậy tôi không biết nếu họ đã cung cấp một cái gì đó như thế này đã được thực hiện, nhưng có vẻ kỳ lạ rằng họ sẽ tạo ra điều này cho bạn, và không có một cách để làm cho nó hoạt động. Tôi biết Jersey 3 sẽ có hỗ trợ Java 8 ra khỏi hộp, nhưng ai biết khi nào heck đó sẽ được phát hành.

+0

Điều này khá thông tin. Cảm ơn nhiều! – user991710

Các vấn đề liên quan