How do I fix this problem it say's 'queryForObject(java.lang.String, java.lang.Object[], java.lang.Class<T>)' is deprecated - java-11

I'm not sure how to fix this since I just started doing spring boot project last Thursday. Unfortunately today is the deadline of my project so frankly I'm quite panicking right now :/
Here is my sample problem code:
#Override
public Integer getCountByEmail(String email) {
return jdbcTemplate.queryForObject(SQL_COUNT_BY_EMAIL, new Object[]{email}, Integer.class);
}
#Override
public User findById(Integer userId) {
return null;
}
Here is the overall code of the Java Class:
package com.example.Spring.boot.Repositories;
import com.example.Spring.boot.Entity.User;
import com.example.Spring.boot.Exceptions.EtAuthException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import java.sql.PreparedStatement;
import java.sql.Statement;
#Repository
public class UserRepositoryImpl implements UserRepository {
private static final String SQL_CREATE = "INSERT INTO SB_USERS(USER_ID,
FIRST_NAME, LAST_NAME, EMAIL," +`"PASSWORD) VALUES(NEXTVAL('SB_USERS_SEQ'), ?, ?, ?, ?)";`
private static final String SQL_COUNT_BY_EMAIL = "SELECT COUNT(*) FROM SB_USERS WHERE EMAIL = ?";
private static final String ID = "SELECT USER_ID, FIRST_NAME, LAST_NAME, EMAIL, PASSWORD " +`"FROM SB_USERS WHERE USER_ID = ?";`
#Autowired
JdbcTemplate jdbcTemplate;
#Override
public Integer create(String firstName, String lastName, String email, String password) throws EtAuthException {
try {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(SQL_CREATE, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, firstName);
ps.setString(2, lastName);
ps.setString(3, email);
ps.setString(4, password);
return ps;
}, keyHolder);
return (Integer) keyHolder.getKeys().get("USER_ID");
}catch (Exception e) {
throw new EtAuthException("Invalid details. Failed to create account");
}
}
#Override
public User findByEmailAndPassword(String email, String password) throws EtAuthException {
return null;
}
#Override
public Integer getCountByEmail(String email) {
return jdbcTemplate.queryForObject(SQL_COUNT_BY_EMAIL, new Object[]{email}, Integer.class);
}
#Override
public User findById(Integer userId) {
return null;
}
}

The following method has been deprecated and must not be used:
public <T> T queryForObject(String sql, #Nullable Object[] args, Class<T> requiredType)
Use the following equivalent method instead:
<T> T queryForObject(String sql, Class<T> requiredType, #Nullable Object... args)
Example:
return jdbcTemplate.queryForObject(SQL_COUNT_BY_EMAIL, Integer.class, email);

Related

How to solve this issue about Java DB connection

There are my codes.
MemberDAO.java
package sec05.ex01;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class MemberDAO {
PreparedStatement pstmt;
Connection connection;
public List<MemberVO> listMembers() {
List<MemberVO> list = new ArrayList<>();
try {
connDB();
String query = "SELECT * FROM t_member";
System.out.println("preparedStatement: " + query);
pstmt = connection.prepareStatement(query);
ResultSet rs = pstmt.executeQuery(query);
while (rs.next()) {
String id = rs.getString("id");
String pwd = rs.getString("pwd");
String name = rs.getString("name");
String email = rs.getString("email");
Date joinDate = rs.getDate("joinDate");
MemberVO vo = new MemberVO();
vo.setId(id);
vo.setPwd(pwd);
vo.setName(name);
vo.setEmail(email);
vo.setJoinDate(joinDate);
list.add(vo);
}
rs.close();
pstmt.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
private void connDB() {
try {
String url = "jdbc:oracle:thin:#localhost:1521:XE";
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("Loaded Oracle Driver");
connection = DriverManager.getConnection(url, "system", "oracle");
System.out.println("Connection created.");
System.out.println("PreparedStatement created.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
MemberServlet.java
package sec05.ex01;
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.io.IOException;
import java.io.PrintWriter;
import java.sql.Date;
import java.util.List;
#WebServlet("/member")
public class MemberServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
MemberDAO dao = new MemberDAO();
List<MemberVO> list = dao.listMembers();
out.print("<html><body>");
out.print("<table border=1><tr align='center' bgcolor='lightgreen'>");
out.print("<td>ID</td><td>PWD</td><td>NAME</td><td>EMAIL</td><td>DATE</td></tr>");
for (MemberVO memberVO : list) {
String id = memberVO.getId();
String pwd = memberVO.getPwd();
String name = memberVO.getName();
String email = memberVO.getEmail();
Date joinDate = memberVO.getJoinDate();
out.print("<tr><td" + id + "</td><td>" + pwd + "</td><td>" + name + "</td><td>" + email + "</td><td>" + joinDate + "</td></tr>");
}
out.print("</table></body></html>");
}
}
MemberVO.java
package sec05.ex01;
import java.sql.Date;
public class MemberVO {
private String id;
private String pwd;
private String name;
private String email;
private Date joinDate;
public MemberVO() {
System.out.println("MemberVO constructor called.");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getJoinDate() {
return joinDate;
}
public void setJoinDate(Date joinDate) {
this.joinDate = joinDate;
}
}
Error Message
But when I use console in IntelliJ, it works.
Database console in IntelliJ
Also, I added a jdbc library. (I'm using jdk17)
IntelliJ Library
I tried to change the library version to 8.
The ClassNotFoundException and NullPointerException occured.

Value Dependent Deserialization with Jackson

I want to deserialize into a data structure. Dependent on the version of the JSON data I want to deserialize into different implementations of the same interface. And this works so far with a custom deserializer.
However, in the data structure I use references. And I expect that when undefined references are encountered an exception is thrown. The way I programmed it, this does not work together with the interface.
I created a small example with a (currently not passing) test case to show the desired behavior.
Additional Information:
In the test case, when I use concrete classes (instead of the interface) in readValue the desired behavior occurs. That is, when I write mapper.readValue(buggy, Database2.class); instead of mapper.readValue(buggy, DatabaseI.class);. But then I lose the ability to abstract from the particular content of the JSON data.
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.btc.adt.pop.scen.objectstreams.Person;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.IntNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
public class Example {
#Test
public void test() throws JsonProcessingException {
ObjectMapper mapper =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
SimpleModule module = new SimpleModule();
module.addDeserializer(DatabaseI.class, new ToyDeserializer());
mapper.registerModule(module);
String correct = "{'version':1,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['b']}]}";
DatabaseI deserCorrect = mapper.readValue(correct, DatabaseI.class);
System.out.println(mapper.writeValueAsString(deserCorrect));
String buggy = "{'version':2,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['FOO']}]}";
assertThrows(Exception.class, () -> {
mapper.readValue(buggy, DatabaseI.class);
}, "The reference FOO is undefined. An Exception should be thrown.");
}
}
class Person {
#JsonProperty("id")
private String id;
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
#JsonIdentityReference(alwaysAsId = true)
private List<Person> friends = new ArrayList<>();
public Person() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Person> getFriends() {
return friends;
}
public void setFriends(List<Person> friends) {
this.friends = friends;
}
}
interface DatabaseI {
}
class Database1 implements DatabaseI {
private int version;
private List<Person> people = new ArrayList<>();
public Database1() {
}
public List<Person> getPeople() {
return people;
}
public void setPeople(List<Person> people) {
this.people = people;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
class Database2 implements DatabaseI {
private String version;
private List<Person> people = new ArrayList<>();
public Database2() {
}
public List<Person> getPeople() {
return people;
}
public void setPeople(List<Person> people) {
this.people = people;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
class ToyDeserializer extends StdDeserializer<DatabaseI> {
protected ToyDeserializer(Class<?> vc) {
super(vc);
}
public ToyDeserializer() {
this(null);
}
#Override
public DatabaseI deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
JsonNode node = mapper.readTree(jp);
int version = (Integer) ((IntNode) node.get("version")).numberValue();
if (version == 1) {
return mapper.treeToValue(node, Database1.class);
} else {
return mapper.treeToValue(node, Database2.class);
}
}
}
This very good question! If you want to understand why no exception is thrown, your class Person must look like this:
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id",
scope = Person.class,
resolver = SimpleObjectIdResolverThrowsException.class
)
#JsonIdentityReference
class Person {
String id;
List<Person> friends = new ArrayList<>();
#ConstructorProperties({"id"})
public Person(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Person> getFriends() {
return friends;
}
public void setFriends(List<Person> friends) {
this.friends = friends;
}
}
class SimpleObjectIdResolverThrowsException extends SimpleObjectIdResolver {
public SimpleObjectIdResolverThrowsException() {
super();
}
#Override
public Object resolveId(ObjectIdGenerator.IdKey id) {
if (this._items == null) {
return null;
}
Object obj = this._items.get(id);
if (obj == null) {
throw new RuntimeException("Unresolved reference for: " + id);
}
return obj;
}
#Override
public ObjectIdResolver newForDeserialization(Object context) {
return new SimpleObjectIdResolverThrowsException();
}
}
Now you can set break point in the method resolveId and see what happens when we de-serialize the string "{'version':1,'people':[{'id':'a','friends':['b','c']},{'id':'b','friends':['c']},{'id':'c','friends':['b']}]}":
The problem is that the objects are processed one after the other and the references from the friends list are not resolved at that time.

How to assert/validate the JSON body and properties returned by a Micronaut controller

I am a Micronaut/Java beginner and I am trying to design some tests for my controllers. I could not find many examples online so here is my question.
Below is the controller with 2 #GET requests:
#Controller("/api/v1")
public class MyController {
private final ClientNetworkList clientNetworkList;
private final ClientStatus clientStatus;
public MyController(
ClientNetworkList clientNetworkList,
ClientStatus clientStatus
){
this.ClientNetworkList = clientNetworkList;
this.ClientStatus = clientStatus;
}
#Get(uri = "/networkList", produces = MediaType.APPLICATION_JSON_STREAM)
Flowable<NetworkListPackage> packagesNetworkList() {
return ClientNetworkList.fetchPackages();
}
#Get(uri = "/channels/{stringParm}/status/", produces = MediaType.APPLICATION_JSON_STREAM)
Flowable<ChannelStatusPackage> packagesStatus(stringParm) {
return ClientStatus.fetchPackages(genesis);
}
}
The java object POJOs:
#Introspected
public class NetworkListPackage {
private List<NetworkList> networkList = null;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public List<NetworkList> getNetworkList() {
return networkList;
}
public void setNetworkList(List<NetworkList> networkList) {
this.networkList = networkList;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
public class NetworkList {
private String name;
private Boolean authEnabled;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getAuthEnabled() {
return authEnabled;
}
public void setAuthEnabled(Boolean authEnabled) {
this.authEnabled = authEnabled;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
#Introspected
public class ChannelStatusPackage {
private String chaincodeCount;
private String txCount;
private String latestBlock;
private String peerCount;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public String getChaincodeCount() {
return chaincodeCount;
}
public void setChaincodeCount(String chaincodeCount) {
this.chaincodeCount = chaincodeCount;
}
public String getTxCount() {
return txCount;
}
public void setTxCount(String txCount) {
this.txCount = txCount;
}
public String getLatestBlock() {
return latestBlock;
}
public void setLatestBlock(String latestBlock) {
this.latestBlock = latestBlock;
}
public String getPeerCount() {
return peerCount;
}
public void setPeerCount(String peerCount) {
this.peerCount = peerCount;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
And the potential tests:
#MicronautTest
class MyControllerTest {
#Inject
#Client("/")
RxStreamingHttpClient client;
#Test
public void verifyChannelStatusPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
//when:
HttpRequest request = HttpRequest.GET("/api/v1/channels/{stringParam}/status/");
Flowable<ChannelStatusPackage> channelStatusPackageStream = client.jsonStream(request, ChannelStatusPackage.class);
Iterable<ChannelStatusPackage> channelStatusPackages = channelStatusPackageStream.blockingIterable();
//then:
//How to assert the returned body compared to the POJO?
//How to handle the parameter in the request url?
#Test
public void verifyNetworkListPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
//when:
HttpRequest request = HttpRequest.GET("/api/v1/networkList");
Flowable<NetworkListPackage> networkListPackageStream = client.jsonStream(request, NetworkListPackage.class);
Iterable<NetworkListPackage> networkListPackages = networkListPackageStream.blockingIterable();
//then:
//How to assert the returned body and compared to the POJO?
//How to assert the returned properties ?
}
}
Based on the previous code, how can I test that the returned bodies and properties of the requests matches the POJOs?
What are the usual test to be carried out?
Thank you very much for helping.
Normaly, the basic assertion start by testing the object type, so this should validate your schema.
An other way to test it is to use RestAssured, witch is a bit more readable.
You need to import the fallowing dependencies in you build.gradle
testImplementation("io.rest-assured:rest-assured:4.2.+")
testImplementation("io.rest-assured:json-schema-validator:4.2.+")
You need test annotation processor to enable micronaut injection and junit 5 for the BeforeEach.
The full test dependencies:
testAnnotationProcessor("io.micronaut:micronaut-inject-java")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("io.micronaut.test:micronaut-test-junit5")
testImplementation("io.rest-assured:rest-assured:4.2.+")
testImplementation("io.rest-assured:json-schema-validator:4.2.+")
testRuntime("org.junit.jupiter:junit-jupiter-engine")
Then you can wright your tests like that:
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
import io.micronaut.http.HttpStatus;
import io.micronaut.runtime.server.EmbeddedServer;
import io.micronaut.test.annotation.MicronautTest;
import io.restassured.RestAssured;
import javax.inject.Inject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
#MicronautTest
class MyControllerTest {
#Inject
private EmbeddedServer embeddedServer;
#BeforeEach
public void setUp() {
RestAssured.port = embeddedServer.getPort();
}
#Test
public void verifyChannelStatusPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
given()
.when()
.pathParam("stringParam", "value")
.get("/api/v1/channels/{stringParam}/status/")
.then()
.statusCode(HttpStatus.OK.getCode())
.body(
"chaincodeCount", equalTo("chaincodeCountValue"),
"txCount", equalTo("txCountValue"),
"latestBlock", equalTo("latestBlockValue"),
"peerCount", equalTo("peerCountValue"),
"additionalProperties.key1", equalTo("additionalPropertyValue1"),
"additionalProperties.key2", equalTo("additionalPropertyValue2")
);
}
#Test
public void verifyNetworkListPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
given()
.when()
.get("/api/v1/networkList")
.then()
.statusCode(HttpStatus.OK.getCode())
.body(
"networkList.name[0]", equalTo("nameValue0"),
"networkList.authEnabled[0]", equalTo("authEnabledValue0"),
"networkList.additionalProperties[0].key1", equalTo("additionalPropertiesValue1"),
"networkList.additionalProperties[0].key2", equalTo("additionalPropertyValue2")
);
}
}
This is not really the way you wanted to do your tests, but I hope it will help.
So I ended up using the "hasItems" matcher or/and the jackson schema matcher.
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
import io.micronaut.http.HttpStatus;
import io.micronaut.runtime.server.EmbeddedServer;
import io.micronaut.test.annotation.MicronautTest;
import io.restassured.RestAssured;
import javax.inject.Inject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.Matchers.hasItems;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
#MicronautTest
class MyControllerTest {
#Inject
private EmbeddedServer embeddedServer;
#BeforeEach
public void setUp() {
RestAssured.port = embeddedServer.getPort();
}
#Test
public void verifyChannelStatusPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
given()
.when()
.pathParam("stringParam", "value")
.get("/api/v1/channels/{stringParam}/status/")
.then()
.statusCode(HttpStatus.OK.getCode())
.body(matchesJsonSchemaInClasspath("channelsStatus.json"))
.body("keySet()",hasItems(
"chaincodeCount",
"txCount",
"latestBlock",
"peerCount",
);
}
#Test
public void verifyNetworkListPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
given()
.when()
.get("/api/v1/networkList")
.then()
.statusCode(HttpStatus.OK.getCode())
.body(matchesJsonSchemaInClasspath("networkList.json"))
.body("networkList.keySet()",hasItems(
"name",
"authEnabled",
);
}
}
``
Another option is to use jsonPath similar to Spring Boot MockMvc ResultMatcher:
testImplementation 'com.jayway.jsonpath:json-path:2.4.0'
testImplementation 'org.hamcrest:hamcrest:2.2'
Get the response as HttpResponse<String> and then use JsonPath.parse(response.body()) to assert the json path:
#Test
public void verifyChannelStatusPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
URI uri = UriBuilder.of("/api/v1/channels/{stringParam}/status/").expand(singletonMap("stringParam", "value"));
HttpResponse<String> response = client.toBlocking().exchange(HttpRequest.GET(uri), String.class);
assertEquals(HttpStatus.OK, response.getStatus());
ReadContext ctx = JsonPath.parse(response.body());
assertThat(ctx.read("$"), isA(Object.class));
assertThat(ctx.read("$.chaincodeCount"), is("chaincodeCountValue"));
}
Example for an endpoint test using Micronaut vs Spring Boot

Retrieve results JAX-RS + Jersey + Jackson

I have this entity class
#Entity
#XmlRootElement
#Table(name="user")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id_user", unique=true, nullable=false)
private String idUser;
#Column(nullable=false, length=50)
private String docnum;
#Column(nullable=false, length=50)
private String email;
#Column(nullable=false, length=50)
private String firstname;
#Column(nullable=false, length=50)
private String lastname;
#Column(nullable=false, length=45)
private String pwd;
//bi-directional many-to-many association to Transaction
#ManyToMany
#JoinTable(
name="transaction_users"
, joinColumns={
#JoinColumn(name="user", nullable=false)
}
, inverseJoinColumns={
#JoinColumn(name="transaction", nullable=false)
}
)
private List<Transaction> transactions;
public User() {
}
public String getIdUser() {
return this.idUser;
}
public void setIdUser(String idUser) {
this.idUser = idUser;
}
public String getDocnum() {
return this.docnum;
}
public void setDocnum(String docnum) {
this.docnum = docnum;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public List<Transaction> getTransactions() {
return this.transactions;
}
public void setTransactions(List<Transaction> transactions) {
this.transactions = transactions;
}
}
generated from a database table. Then i have this rest service
#Path("service/2.0")
public class ServiceTest {
#GET
#Path("/users")
#Produces(MediaType.APPLICATION_JSON)
public Response getUser() {
EntityManager entityManager = EntityManagerUtil.getEntityManager();
entityManager.getTransaction().begin();
Query q = entityManager.createQuery("SELECT u FROM User u");
#SuppressWarnings("unchecked")
List<User> listOfUser = q.getResultList();
System.out.print(listOfUser);
return Response.ok(listOfUser).build();
}
I'm (supposed) to be using the jackson API to handle json but i'm not using maven. For this reason, i've added in my buildpath the following .jars:
jackson-annotations-2.9.3.jar
jackson-core-2.9.3.jar
jackson-databind-2.9.3.jar
jackson-jaxrs-base-2.9.3.jar
jackson-module-jaxb-annotations-2.9.3.jar
jersey-media-json-jackson-2.26.jar
jackson-jaxrs-json-provider-2.9.3.jar
Then i have an ApplicationConfig.java class
package prova;
import com.fasterxml.jackson.jaxrs.json.*;
import org.glassfish.jersey.server.ResourceConfig;
import javax.ws.rs.ApplicationPath;
#ApplicationPath("rest")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
packages("com.fasterxml.jackson.jaxrs.json");
packages("prova");
}
}
When i try to submit a GET request with postman, i obtain an "HTTP 500 internal server error" with the description:
"The server encountered an unexpected condition that prevented it from fulfilling the request."
While from the eclipse console i can see
[EL Fine]: sql: 2017-12-16 17:44:54.251--ServerSession(1869059368)--
Connection(771012214)--Thread(Thread[http-nio-8080-exec-80,5,main])--
SELECT id_user, DOCNUM, EMAIL, FIRSTNAME, LASTNAME, PWD FROM user
[prova.User#3c713cb0, prova.User#49e51730, prova.User#d9ecdd7,
prova.User#383fe468]dic 16, 2017 5:44:54
PM org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWr
iterInterceptor aroundWriteTo
GRAVE: MessageBodyWriter not found for media type=application/json,
type=class java.util.Vector, genericType=class java.util.Vector.
So what i can deduce is that the query is correctly executed and it returns an array of 4 object (prova is the name of my entity manager) but then i have the GRAVE:MessageBodyWriter Error
What the hell i'm not doing correctly?why i can not retrieve my JSON data?
Thanks
UPDATE
Following the advice, i've modified the GET resource into
#GET
#Path("/users")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String getUser() {
return String.valueOf(10+4);
}
and submitting the GET request gives me the expected JSON answer from Postman "14"....
Can the problem be the conversion of a List into Json?if yes, what to do?
Thanks
UPDATE 2
I've edited the code of the REST resource in this way:
#GET
#Path("/users")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String getUser() {
EntityManager entityManager = EntityManagerUtil.getEntityManager();
entityManager.getTransaction().begin();
Query q = entityManager.createQuery("SELECT u FROM User u");
List<User> listOfUser = q.getResultList();
System.out.print(listOfUser);
if (listOfUser.isEmpty()) {
System.out.println("VOID LIST");
entityManager.close();
return String.valueOf(2);
}
for (User user : listOfUser) {
System.out.println(user.getFirstname());
System.out.println("---");
}
return String.valueOf(3);
}
The postman Output is "3" so, everything fine while the consoloe output is:
[EL Fine]: sql: 2017-12-17 13:48:33.214--ServerSession(286337061)--
Connection(2132504260)--Thread(Thread[http-nio-8080-exec-2,5,main])--
SELECT id_user, DOCNUM, EMAIL, FIRSTNAME, LASTNAME, PWD FROM USER
[prova.User#2d3017ff, prova.User#6361d00, prova.User#7ab0944a,
prova.User#5945162f]
matteo
---
tony
---
bruce
---
peter
---
which is perfectly consistent with what i have in the table of the DB... :(
Try to convert your response entity in an array of users. There is proper equivalent for array in json.
Other way ist to have a wrapper class for your list of users.
#XmlType
#XmlRootElement
class Wrapper {
#XmlElement
List<User> users;
}
Return this in your response.

Getting class cast exception when doing a POST request using JAX-RS with hibernate backend

I have a simple User POJO class, its definition is as follows:
package models;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#XmlRootElement
#Table(name="USER",uniqueConstraints={#UniqueConstraint(columnNames="email")})
public class User {
#XmlElement
private String name;
#Id
#XmlElement
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#XmlElement
private String email;
#XmlElement
private int age;
#Override
public String toString() {
return "User [name=" + name + ", id=" + id + ", email=" + email + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
and my resource mapping is as follows:
#POST
#Produces(MediaType.TEXT_HTML)
#Consumes(MediaType.APPLICATION_JSON)
#Path("/Person")
public Response insertPerson(User user) {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
int uid = (Integer)session.save(user);
tx.commit();
session.close();
return Response.status(201).entity(uid).build();
}
When i do a post request using PostMan i am getting this exception on server:
Dec 20, 2015 9:44:42 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Jersey Web Application] in context with path [/expenseManagement] threw exception [Exception [EclipseLink-6065] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.QueryException
Exception Description: Cannot add the object [User [name=manjunath, id=100, email=manjunath#gmail.com, age=15]], of class [class models.User], to container [class models.User].
Internal Exception: java.lang.ClassCastException: models.User cannot be cast to java.util.Collection] with root cause
java.lang.ClassCastException: models.User cannot be cast to java.util.Collection
I have provided message body readers as well, I don't know where i am going wrong, can someone please help.
The content you send is surrounded by [ and ] marking it an array, not an object. Try sending only this String:
{"name":"manjunath", "age":15, "id":100, "email":"manjunath#gmail.com"}
Good Luck