質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

サーブレットからjson形式のデータをレスポンスしたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,207

score 109

package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.ObjectMapper;

import dao.USER_DB;
import model.UserDTO;


@WebServlet("/Userlist")
public class Userlist extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public Userlist() {
        super();
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

                  //ajaxのパラメータルリクエストを取得(中身"user")        
        String button = request.getParameter("one");

         if( button.equals("user")) {

             try {

            //ユーザ情報をデータベースから取得するクラス
             USER_DB user_db = new USER_DB();

             //ユーザid と ユーザ名の値がセットさせたdtoクラスが格納させた配列を取得
             ArrayList<UserDTO> userlist =  (ArrayList<UserDTO>) user_db.getUser();


              ArrayList<Integer>  userId = new ArrayList<Integer>();
             List<String>  userName = new ArrayList<String>();

             for(int i = 0; i < userlist.size(); i++) {

                 userName.add(userlist.get(i).getName());                 
             }


              ObjectMapper mapper = new ObjectMapper();

              Map<Integer, String> resMap = new HashMap<>();


              for(int  i = 0; i < userName.size(); i++) {

                  resMap.put(userId.get(i),userName.get(i));             
                 }


              String resJson = mapper.writeValueAsString(resMap);

              response.setContentType("application/json");
                response.setHeader("Cache-Control", "nocache");
                response.setCharacterEncoding("utf-8");


                PrintWriter out = response.getWriter();
                out.print(resJson);

              out.close();

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

    }
}

上記のコードを実行すると  catch(Exception e)  されてしまいます。

調べても、原因が分からず解決出来なかったのでアドバイス頂けると助かります。

--追記--
コンソールエラー内容
重大: Servlet.service() for servlet [servlet.Userlist] in context with path [/webkensyu] threw exception [サーブレットの実行により例外を投げました] with root cause [月 

javaでjsonを扱うために必要なことをネットで調べてみました。
自分なりに理解して書いてみたのですが、 コンソールエラーが何のエラーか分からず、対処出来ずにいます。

--追記2--

$('#user_list2').on('click',function(){

    var val= $('#user_list').val();

    $.ajax({

        url:"Userlist",
        type:"POST",
        cache:false,
        data:{'user':val},  
    //    dataType:"json",
        success: function(data){        
            userlist = data;
            $("#test1").text(userlist);            
        },
          error : function(XMLHttpRequest, textStatus, errorThrown) {
              alert("エラーが発生しました:" + textStatus +":\n" + errorThrown);
            }                
    });

});

実行するとjquery の  error : functionで

エラーが発生しました:error:
Not Found
とアラートされます。

--追記3--

Chromeコンソールには
POST http://localhost:8080/webkensyu/Userlist 500 (Internal Server Error)
send @ jquery.min.js:2
ajax @ jquery.min.js:2
(anonymous) @ kensyu.js:12
dispatch @ jquery.min.js:2
v.handle @ jquery.min.js:2
とエラーが出てしまいます。

実行するとjquery の  error : functionで

エラーが発生しました:error:
internal Server Error
とアラートされます。
--追記4--
修正後コード

package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.ObjectMapper;

import dao.USER_DB;
import model.UserDTO;


@WebServlet("/Userlist")
public class Userlist extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public Userlist() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

         try {
        request.setCharacterEncoding("UTF-8");

        //ajaxのパラメータルリクエストを取得(中身"user")        
String button = request.getParameter("one");

//if( button.equals("user")) {



  //ユーザ情報をデータベースから取得するクラス
   USER_DB user_db = new USER_DB();

   //ユーザid と ユーザ名の値がセットさせたdtoクラスが格納させた配列を取得
   ArrayList<UserDTO> userlist =  (ArrayList<UserDTO>) user_db.getUser();


    List<Integer>  userId = new ArrayList<Integer>();
   List<String>  userName = new ArrayList<String>();


   //ユーザIdを<Integer>型のListに入れ直し
   for(int i = 0; i < userlist.size(); i++) {

       userId.add(userlist.get(i).getId());                 
   }

   //ユーザNameを<String>型のListに入れ直し
   for(int i = 0; i < userlist.size(); i++) {

       userName.add(userlist.get(i).getName());                 
   }



   Map<String, String> userlists = new HashMap<>();

   //MapのキーにユーザId, 値のNameをセット
   for(int i= 0; i < userlist.size(); i++) {

       userlists.put(String.valueOf(userId.get(i)), userName.get(i));
   }

  // JSONObject obj = new JSONObject(userlists);

   String json = new ObjectMapper().writeValueAsString(userlists);
   System.out.println(json);
     PrintWriter out = response.getWriter();
     out.print(json);

 //  Gson gson = new Gson();
  // String json = gson.toJson(userName.get(0));


    //  PrintWriter out = response.getWriter();
    //  out.print(obj);



   // Map<String, Object> map = new HashMap<>();
  // map.put("name", "Taro Tanaka");
  // map.put("age", 30);

   //JSONObject obj = new JSONObject(map);

   //   PrintWriter out = response.getWriter();
   //   out.print(obj);

    //out.close();

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

}

修正後のコードを実行すると 

jquery.min.js:2 POST http://localhost:8080/webkensyu/Userlist 500 (Internal Server Error)

とエラーが出てしまいます。

PrintWriter out = response.getWriter();
out.print(json);
で、mapをjsonに変換したデータを文字列としてストリームに出力しています。

例えば  String aaa = "aaa";

PrintWriter out = response.getWriter();
out.print(aaa);

このような例だと上手くjqueryの方で受けっとってconsoleなどに出力できます。

原因が全然分からなかったので、アドバイス頂けると助かります。

--追記5--
ObjectMapper ObjectMapper = new ObjectMapper();

でインスタンス化させようとするとエラーになっているようです。
調べても解決出来なかったのでアドバイス頂けると助かります。

--追記6--

情報: Server version:        Apache Tomcat/7.0.88 [火 10 01 16:43:27 JST 2019]
情報: Server built:          May 7 2018 11:12:57 UTC [火 10 01 16:43:27 JST 2019]
情報: Server number:         7.0.88.0 [火 10 01 16:43:27 JST 2019]
情報: OS Name:               Windows 8.1 [火 10 01 16:43:27 JST 2019]
情報: OS Version:            6.3 [火 10 01 16:43:27 JST 2019]
情報: Architecture:          amd64 [火 10 01 16:43:27 JST 2019]
情報: Java Home:             C:\pleiades\java\7\jre [火 10 01 16:43:27 JST 2019]
情報: JVM Version:           1.7.0_80-b15 [火 10 01 16:43:27 JST 2019]
情報: JVM Vendor:            Oracle Corporation [火 10 01 16:43:27 JST 2019]
情報: CATALINA_BASE:         Dwtp.deploy=C:\pleiades\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps [火 10 01 16:43:27 JST 2019]
情報: Command line argument: -Djava.endorsed.dirs=C:\pleiades\tomcat\7\endorsed [火 10 01 16:43:27 JST 2019]
情報: Command line argument: -Dfile.encoding=UTF-8 [火 10 01 16:43:27 JST 2019]
情報: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\pleiades\java\7\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/pleiades/eclipse/jre/bin/../jre/bin/server;C:/pleiades/eclipse/jre/bin/../jre/bin;C:/pleiades/eclipse/jre/bin/../jre/lib/amd64;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\skoga\Program Files (x86)\VMware\VMware vSphere CLI\Perl\site\bin;C:\skoga\Program Files (x86)\VMware\VMware vSphere CLI\Perl\bin;c:\Program Files (x86)\Intel\iCLS Client\;c:\Program Files\Intel\iCLS Client\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x64;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program \Local\atom\bin;C:\pleiades\eclipse;;. [火 10 01 16:43:27 JST 2019]
情報: サービス Catalina を起動します [火 10 01 16:43:27 JST 2019]
情報: Starting Servlet Engine: Apache Tomcat/7.0.88 [火 10 01 16:43:27 JST 2019]
情報: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. [火 10 01 16:43:30 JST 2019]
情報: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. [火 10 01 16:43:32 JST 2019]
情報: Starting ProtocolHandler ["http-bio-8080"] [火 10 01 16:43:32 JST 2019]
情報: Starting ProtocolHandler ["ajp-bio-8009"] [火 10 01 16:43:32 JST 2019]
情報: Server startup in 4651 ms [火 10 01 16:43:32 JST 2019]
重大: Servlet.service() for servlet [servlet.Userlist] in context with path [/webkensyu] threw exception [サーブレットの実行により例外を投げました] with root cause [火 10 01 16:43:35 JST 2019]

内部サーバ起動時のコンソール情報

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kokok

    2019/10/01 12:07

    すみません。削除依頼しておきました。

    eclipseのコンソール?と Chromeのコンソールを確認しました。

    キャンセル

  • m.ts10806

    2019/10/01 13:04

    catchに入ったかどうかの確認はされてないわけですよね?
    デバッグモードでステップ実行するとどこを通ってましたか?

    キャンセル

  • kokok

    2019/10/01 13:26

    catchまで入ってませんでした。
    String json = new ObjectMapper().writeValueAsString(userlists);
    で処理が止まってしまいます。

    キャンセル

回答 1

checkベストアンサー

+1

JavaWebアプリケーションの仕様として、動作に必要なライブラリは WEB-INF/lib の中に jarファイルを配置する必要があります。

利用されているjackson-core.jar や jackson-databind.jar はビルドパスに追加されていると思うのですが、動的Webアプリケーションとしてプロジェクトが作られているかと思いますので、その場合はWEB-INF/lib に入れるだけで、自動的にビルドパスへ追加され、サーバに搭載されます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/29 15:58

    回答ありがとうございます。
    とても参考になりました。
    WEB-INF/lib の中に jarファイルを配置したところ、上手くjson形式での受け渡しが出来ました。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る