Issue
I have a Servlet code which I am running to query data from MySQL and converting it to a json object with gson. Ultimately I want to use axios in my react app to show this in the frontend. I am always running into problems with GSON though and it's never compiling correctly. Earlier it was version 2.8 so I upgraded to 2.9 to remove the reflection error, but now I am getting this error.
com.google.gson.JsonIOException: Failed making field 'java.lang.ref.Reference#referent' accessible; either change its visibility or write a custom TypeAdapter for its declaring type
My servlet program code:
package org.datafetching;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.sql.*;
import com.google.gson.Gson;
@WebServlet("/fetchdata")
public class FetchData extends HttpServlet {
private static final long serialVersionUID = 1L;
public FetchData() {
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/grey_goose", "", "");
PreparedStatement ps=conn.prepareStatement("select * from table limit 10");
ResultSet rs=ps.executeQuery();
Gson gson = new Gson();
String tablejson = gson.toJson(rs);
PrintWriter printWriter = response.getWriter();
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
printWriter.print(tablejson);
printWriter.flush();
//printWriter.write(tablejson);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Object class code
package servdemo.registration.model;
public class Employee {
private String firstName;
private String lastName;
private String username;
private String password;
private String address;
private String contact;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
}
Solution
You should map result set to an Object which represent a table. For example if you have table named People and it have field name and age.
Example class
public Class People {
private String name;
private Integer age;
... //Getters and Setters here
}
And here is code for mapping data.
List<People> staffs = new ArrayList<People>();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
People people = new People(resultSet.getString("name"),
resultSet.getInt("age"));
staffs.add(people);
}
resultSet.close();
preparedStatement.close();
connection.close();
Gson gson = new Gson();
String yourJson = gson.toJson(staffs);
This code will map your result set. Of course you need to create object based on your table so after changing this code a bit you should make it work.
Answered By - Szprota21
Answer Checked By - Pedro (JavaFixing Volunteer)