2017-04-06 6 views
0

Retrofit을 사용하여 내 REST API에 연결합니다. 이 코드는 내가 finally() 블록에 아래의 코드 라인을 대체 그러나 경우 아래의 예외`RequestDispatcher`가 실행될 때의 NullPointerException

java.lang.NullPointerException 
    at com.tekhinno.xxx.signup.SignUpLoaderServlet$1.onResponse(SignUpLoaderServlet.java:80) 
    at retrofit2.OkHttpCall$1.callSuccess(OkHttpCall.java:132) 
    at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:111) 
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135) 
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

를 발생 아래 코드

import com.google.gson.Gson; 
    import com.google.gson.GsonBuilder; 
    import java.io.IOException; 
    import java.io.PrintWriter; 
    import java.util.Date; 
    import java.util.List; 
    import java.util.logging.Level; 
    import java.util.logging.Logger; 
    import javax.servlet.RequestDispatcher; 
    import javax.servlet.ServletException; 
    import javax.servlet.http.HttpServlet; 
    import javax.servlet.http.HttpServletRequest; 
    import javax.servlet.http.HttpServletResponse; 
    import retrofit2.Call; 
    import retrofit2.Callback; 
    import retrofit2.Response; 
    import retrofit2.Retrofit; 
    import retrofit2.converter.gson.GsonConverterFactory; 

    /** 
    * 
    * @author The Ace 
    */ 
    public class SignUpLoaderServlet extends HttpServlet { 

     /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> 
     * methods. 
     * 
     * @param request servlet request 
     * @param response servlet response 
     * @throws ServletException if a servlet-specific error occurs 
     * @throws IOException if an I/O error occurs 
     */ 
     protected void processRequest(final HttpServletRequest request, final HttpServletResponse response) 
       throws ServletException, IOException { 
      response.setContentType("text/html;charset=UTF-8"); 
      PrintWriter out = response.getWriter(); 
      System.out.println("RUNNING!!!!!!!!!!!"); 

      try { 
       GsonBuilder gsonBuilder = new GsonBuilder(); 
       gsonBuilder.registerTypeAdapter(Date.class, new DateTypeDeserializer()); 
       Gson gson = gsonBuilder.create(); 

       Retrofit retrofit = new Retrofit.Builder() 
         .baseUrl(BaseURLs.MESSAGING_URL) 
         .addConverterFactory(GsonConverterFactory.create(gson)) 
         .build(); 

       RestEndPointsInterface endPoint = retrofit.create(RestEndPointsInterface.class); 
       Call<List<ProfesionalBodyList>> call = endPoint.getAllProfesionalBodyLists(); 
       call.enqueue(new Callback<List<ProfesionalBodyList>>() { 

        @Override 
        public void onResponse(Call<List<ProfesionalBodyList>> call, Response<List<ProfesionalBodyList>> rspn) 
        { 
         try { 
          List<ProfesionalBodyList> body = rspn.body(); 


          for(int i=0;i<body.size();i++) 
          { 
           System.out.println(body.get(i).getProfessionalBody()); 
          } 

RequestDispatcher requestDispatcher = request.getRequestDispatcher("/create-account.jsp"); 
          requestDispatcher.forward(request, response); 


         } catch (Exception ex) { 
          ex.printStackTrace(); 
         } 
        } 

        @Override 
        public void onFailure(Call<List<ProfesionalBodyList>> call, Throwable ex) { 
         ex.printStackTrace(); 
        } 
       }); 



      } finally { 


      } 
     } 

     // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> 
     /** 
     * Handles the HTTP <code>GET</code> method. 
     * 
     * @param request servlet request 
     * @param response servlet response 
     * @throws ServletException if a servlet-specific error occurs 
     * @throws IOException if an I/O error occurs 
     */ 
     @Override 
     protected void doGet(HttpServletRequest request, HttpServletResponse response) 
       throws ServletException, IOException { 
      processRequest(request, response); 
     } 

     /** 
     * Handles the HTTP <code>POST</code> method. 
     * 
     * @param request servlet request 
     * @param response servlet response 
     * @throws ServletException if a servlet-specific error occurs 
     * @throws IOException if an I/O error occurs 
     */ 
     @Override 
     protected void doPost(HttpServletRequest request, HttpServletResponse response) 
       throws ServletException, IOException { 
      processRequest(request, response); 
     } 

    } 

을 확인하시기 바랍니다, 문제는 사라졌다.

RequestDispatcher requestDispatcher = request.getRequestDispatcher("/create-account.jsp"); 
requestDispatcher.forward(request, response); 

onResponse()에서 작동하지 않는 이유가 확실하지 않습니다. 앞으로 동작이 일어나기 전에 REST API에서 항목을로드하므로 거기에서 실행하는 것이 중요합니다.

아이디어가 있으십니까?

+1

비동기 API를 사용 중입니다. 비동기 API는 백그라운드 스레드에서 요청을 보낸 다음 나중에 응답을 사용할 수있을 때 다시 전화를 걸고 요청 처리 스레드를 차단하지 않습니다. 따라서 요청은 onResponse 콜백이 실행될 때 이미 처리됩니다. –

+0

@JBNizet : 고마워요. 그렇다면이 상황을 어떻게 처리 할 수 ​​있습니까? –

답변

0

주로 호출이 Asynchronous이고 requestDispatcher 개체가 이미 실행 되었기 때문에 문제가 발생했습니다. 그런 다음 REST 호출이 작업로드를 완료 할 때까지 응답을 유지하는 것입니다. 즉, 할 Synchronous.

개장은 Synchronous 방식으로 수행 할 수도 있습니다. 아래는 코드입니다.

protected void processRequest(final HttpServletRequest request, final HttpServletResponse response) 
      throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 
     PrintWriter out = response.getWriter(); 
     System.out.println("RUNNING!!!!!!!!!!!"); 

     try { 
      GsonBuilder gsonBuilder = new GsonBuilder(); 
      gsonBuilder.registerTypeAdapter(Date.class, new DateTypeDeserializer()); 
      Gson gson = gsonBuilder.create(); 

      Retrofit retrofit = new Retrofit.Builder() 
        .baseUrl(BaseURLs.MESSAGING_URL) 
        .addConverterFactory(GsonConverterFactory.create(gson)) 
        .build(); 

      RestEndPointsInterface endPoint = retrofit.create(RestEndPointsInterface.class); 
      Call<List<ProfesionalBodyList>> call = endPoint.getAllProfesionalBodyLists(); 
      body = call.execute().body(); 

      for (int i = 0; i < body.size(); i++) { 
       System.out.println(body.get(i).getProfessionalBody()); 
      } 

     } finally { 
      RequestDispatcher requestDispatcher = request.getRequestDispatcher("/create-account.jsp"); 
      request.setAttribute("ProfesionalBodyList", body); 
      requestDispatcher.forward(request, response); 
     } 
    } 

Simpy는 call.execute().body();이라고 말하는 곳에주의하십시오. 이것은 Synchronous 호출입니다.