Pertanyaan MultiException ketika custom jersey param melempar pengecualian


CATATAN: Semua kode untuk mereproduksi masalah ini tersedia di https://gist.github.com/SrikanthRao/c9fc35e6fe22a74ab40c

http: // localhost: 8080 / tanggal / kacang? tanggal = 2014-13-23  (menggunakan BeanParam) menghasilkan  "{" code ": 500," message ":" Ada kesalahan saat memproses permintaan Anda. Ini telah dicatat (ID 48be9aa43bd49547). "}" Tanpa menambahkan MultiExceptionMapper ke jersey.

Jika saya menambahkan MultiExceptionMapper ke jersey, url di atas akan menghasilkan

"Tanggal tidak dalam format YYYY-MM-DD atau tidak valid"

http: // localhost: 8080 / tanggal? tanggal = 2014-13-23 (direct @QueryParam parameter) menghasilkan "Tanggal tidak dalam format YYYY-MM-DD atau tidak valid"

Beberapa pertanyaan:

  1. Apakah ini cara yang tepat untuk menangani validasi input dengan cara yang lebih bersih?
  2. Saya mengharapkan ini bekerja tanpa perlu menambahkan MultiExceptionMapper saya sendiri. Bukankah Jersey mendukung kebiasaan * Params di dalam POJO yang disuntikkan sebagai @BeanParam dalam metode sumber daya?

Di sini adalah tumpukan jejak yang dihasilkan saat meminta (tanpa menambahkan MultiExceptionMapper ke jersey). Ofcourse menghapus jejak panjang. Beri tahu saya jika Anda membutuhkan pelacakan tumpukan lengkap.

    ERROR [2015-05-04 18:48:33,366] io.dropwizard.jersey.errors.LoggingExceptionMapper: Error handling a request: 0f23e4de758653d6
    ! javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
    ! at io.dropwizard.jersey.params.AbstractParam.<init>(AbstractParam.java:28) ~[dropwizard-jersey-0.8.1.jar:0.8.1]
    ! at com.fun.myapp.LocalDateTimeParam.<init>(LocalDateTimeParam.java:20) ~[classes/:na]
    ! at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_45]
...
...
Causing: org.glassfish.hk2.api.MultiException: A MultiException has 3 exceptions.  They are:
! 1. javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
! 2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.fun.myapp.PaginationFilters errors were found
! 3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.fun.myapp.PaginationFilters
! 
! at org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:88) ~[hk2-locator-2.4.0-b10.jar:na]
! at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:252) ~[hk2-locator-2.4.0-b10.jar:na]
! at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360) ~[hk2-locator-2.4.0-b10.jar:na]
! at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471) ~[hk2-locator-2.4.0-b10.jar:na]
....
....
WARN  [2015-05-04 18:48:33,401] org.glassfish.jersey.internal.Errors: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 3
javax.ws.rs.WebApplicationException: HTTP 400 Bad Request
    at io.dropwizard.jersey.params.AbstractParam.<init>(AbstractParam.java:28)
    at com.fun.myapp.LocalDateTimeParam.<init>(LocalDateTimeParam.java:20)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
...
...
MultiException stack 2 of 3
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.fun.myapp.PaginationFilters errors were found
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:249)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:360)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
...
...
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: resolve on com.fun.myapp.PaginationFilters
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:389)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
    at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)

Saya sudah menanyakan pertanyaan ini di grup google pengguna-dropwizard - https://groups.google.com/forum/#!topic/dropwizard-user/yW-RXSSlspY


11
2018-04-29 19:07


asal


Jawaban:


pertanyaan 1

Menurut dokumentasi inti dropwizard, saya melihat dua kemungkinan implementasi untuk validasi input:

  • melalui anotasi validasi

Anda dapat menambahkan anotasi validasi ke bidang kelas representasi Anda dan memvalidasi mereka ...

Ini sepertinya tidak cocok untuk kasus Anda. Faktanya, tidak ada penjelasan yang tersedia untuk LocalDateTime dan membuat satu petunjuk untuk mengurai LocalDateTime dua kali: untuk validasi dan untuk pengaturan lahan kacang.

  • Melalui penanganan kesalahan:

Jika Anda ingin lebih banyak kontrol, Anda juga dapat menyatakan Penyedia Jersey di Lingkungan Anda untuk memetakan Pengecualian untuk respons tertentu dengan menghubungi Daftar # (Obyek) JerseyEnvironment dengan implementasi javax.ws.rs.ext.ExceptionMapper ...

Untuk menjawab pertanyaan pertama Anda, saya akan mengatakan bahwa menggunakan mapper pengecualian baik-baik saja dalam kasus Anda.

Pertanyaan 2 Debugging kedua metode isValidDate menunjukkan bahwa versi @BeanParam menggunakan ClazzCreator.java sementara @QueryParam tidak. Kelas ini bertanggung jawab untuk menciptakan instance kelas kacang. Jika Anda memeriksa 226 baris kelas, Anda akan melihat bahwa itu mengumpulkan beberapa pengecualian sementara menguraikan masukan dengan beberapa kesalahan. Ini harus memungkinkan pelaporan beberapa kesalahan yang terkait dengan bidang kacang yang berbeda, termasuk beberapa pengecualian berikutnya.

Jawabannya adalah bahwa Jeysey mendukung * Params di dalam POJO. Namun, pengecualian terkait dienkapsulasi menjadi MultiException dalam konteks @BeanParam. Akibatnya, jika Anda berencana menambahkan bidang lain ke PaginationFilters, Anda harus mempertimbangkan untuk melaporkan beberapa kesalahan dalam pesan yang dipetakan.


3
2018-05-08 00:01



1 / untuk memvalidasi tanggal, saya lebih suka mengurai "tanggal" sendiri. Sederhana dan bersih. Berikut ini beberapa kode yang berfungsi:

package com.rizze.stackoverflow;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;



@Path("/test")
public class TestRessource {


    @GET    
    @Path("is")
    @Produces({"application/json"})
    public Response isDateValid(@QueryParam("date") String dateString){

        if(dateString == null) 
            return Response.status(400).entity("date is null").build();
        Date thedate =null;
        try {
            thedate = new SimpleDateFormat("yyyy-mm-dd").parse(dateString);
        } 
        catch (ParseException e) {
            return Response.status(400).entity("date malformed").build();
        }
        System.out.println("time:"+thedate.getTime());
        return Response.ok()
                .entity("{\"time\":"+ thedate.getTime() +"}")
                .header("source", "com.rizze")
                .build();
    }
}

dalam kode ini Anda akan memanggil

http://localhost:8080/test/is?date=2014-12-12

akan kembali :

{"time":1389496320000}

lihat intinya: https://gist.github.com/jeorfevre/6e46ae8d9232f7f9d7cc

2 / untuk menangkap pengecualian, praktik yang baik adalah menangkap pengecualian tingkat server dengan Penyedia (dengan mendaftarkan penyedia ke aplikasi Anda). Dan untuk pengecualian tingkat Aplikasi, maksimalkan pengecualian Anda sendiri menggunakan response.status (status pengecualian) .....

Silakan lihat tok saya, saya telah menambahkan _ServerError.class dan saya telah mendaftarkannya di aplikasi:

  //register a mapper by rizze
        environment.jersey().register(_ServerError.class);

silakan lihat dokumen resmi yang jelas: dok resmi representasi jersey


0
2018-05-08 02:58