I've came upon a problem and I am struggling for 5 hours.
I've created a Java API (right now just for testing) in Eclipse using Jersey and this is my first time creating an API.
I am using Postman to test it.
When calling the GET method to just return a string "Hello" it's working great.
The problem is when I try the POST method that accepts an object of a class Person as an input parameter and also just returns string "Hello" I get Internal Server Error. I know I am not using the Person object right now, but I am just testing the input parameter from Postman and it's not working.
I tried to change the function in the API to be without an input parameter and just to be POST and it works like that, it prints the "Hello", but I need that input parameter for later...
The problem is somewhere around the creation of the object in the xml code in Postman maybe, I don't know.
Any suggestion is welcomed.
Here is the code for the API with the methods get and post
#Path("/employee")
public class API {
#POST
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
#Path("/examplepost")
public String examplePost(Person p) {
return "Hello";
}
#GET
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
#Path("/exampleget")
public String exampleGet() {
return "Hello";
}
}
This is the Person class:
#XmlRootElement(name = "person")
public class Person {
private String name;
private int age;
private int id;
public Person(String name, int age, int id) {
super();
this.name = name;
this.age = age;
this.id = id;
}
public Person() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Override
public String toString(){
return id+"::"+name+"::"+age;
}
}
And these are the results from Postman
GET Method
POST Method
The problem is that the argument Person p does not have the right class type. the function is consuming an XML not an instance of Person. So you have to use JAXBElement that represents information about an Xml Element
public String examplePost(JAXBElement<Person> p) {
Person person = p.getValue();
return "Hello";
}
[OPTIONAL] Also in PostMan: you have to specify what data you are sending by adding the xml version at the beginning
<?xml version="1.0"?>
<Person>
<!-- Person's attributes -->
</Person>
Related
I was writing a program to return JSON object using gson and I discovered something peculiar. Basically when I wanted to convert following object to JSON it gave me null.
Customer customer = new Customer() {
{
setId(1);
setName("Foo bar");
setAddress("Some Address");
}
};
System.out.println(gson.toJson(customer));
where Customer looks like this
public class Customer{
int id;
String name;
String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
but when I created object properly like
Customer customer = new Customer();
customer.setId(1);
customer.setName("Foo bar");
customer.setAddress("Some Address");
System.out.println(gson.toJson(customer));
it worked perfectly fine and gave output as supposed to.
Why does it matter how I create my objects. Is there difference between two methods?
The reason the first case it is returning null because 'customer' object's class is an anonymous one which clazz.isAnonymousClass() return true
See below for GSon implementation
I am using Jersy for producing Json in an application.
The code snippet which produces Json is as follows
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("sample")
public List<test> displaySampleMessage(#PathParam("id") int id)
{
System.out.println(id);
List<test> sample1 = new ArrayList<>();
test temp1 = new test();
temp1.setName("abc");
sample1.add(temp1);
return sample1;
}
Test is simple java class with the following code
package webServiceTester;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class test
{
private String name;
private int age;
public test()
{
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public test(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
Then when I run this web service I get the following output
I do not t want to get age = 0 here because I have not set the age property of my object.
What is its solution. I want age to be appeared if I set the value otherwise it should not appear..
Use Jakson, here you can find a
JSON example with Jersey + Jackson.
So you can use #JsonSerialize annotation to exclude null or empty fields.
#JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
or
#JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)
However it's not a good practice to exclude null or empty fields in restful applications because it may lead errors in client side.
I have to update my resources partially using PATCHrequest whose body is a JSON. Below is my POJO for OwnerDetails. I am using play-framework with Hibernate.
public class OwnerDetailsVO {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I have created rows in MySQL for the Entity Object which corresponds to this value object (VO).
My JSON body for PATCH request is,
PATCH /owners/123
[
{ "op": "replace", "path": "/name", "value": "new name" }
]
I have configured the correct route to the method in the routes file.
Here is the OwnerController class which should process the JSON request. I am using POSTMAN to send the requests.
public class OwnerController extends Controller {
public Result create() {
Form<OwnerDetailsVO> odVOForm = Form.form(OwnerDetailsVO.class).bindFromRequest();
if(odVOForm.hasErrors()) {
return jsonResult(badRequest(odVOForm.errorsAsJson()));
}
OwnerDetailsVO odVO = odVOForm.get();
int id = odProcessor.addOwnerDetails(odVO);
return jsonResult(ok(Json.toJson("Successfully created owner account with ID: " + id)));
}
public Result update(int id) {
//I am not sure how to capture the data here.
//I use Form to create a new VO object in the create() method
}
}
How should the request be captured inside the update() function so that I can partially update my resource? I am not able to find good documentations to know about PATCH operations for Play! Framework.
Edit: I have seen about WSRequest for Patch operation, but I am not sure how to use that. Will that be helpful?
This is a sample code using ebeans in Play Framework
public Item patch(Long id, JsonNode json) {
//find the store item
Item item = Item.find.byId(id);
if(item == null) {
return null;
}
//convert json to update item
Item updateItem;
updateItem = Json.fromJson(json, Item.class);
if(updateItem.name != null){
item.name = updateItem.name;
}
if(updateItem.price != null){
item.price = updateItem.price;
}
item.save();
return item;
}
I am just becoming familiar with the Ninja framework. I am experimenting with parsing forms into Java objects. However, though this appears to follow the documentation, it does not appear to be working.
route:
router.GET().route("/create_user").with(UserController.class, "createUser");
Controller:
public Result createUser(Context context, UserTest userTest) {
System.out.println(userTest);
return Results.text().renderRaw("success");
}
UserTest:
public class UserTest {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
return "UserTest [name=" + name + ", age=" + age + "]";
}
}
Input:
http://localhost:8080/create_user?name=test&age=5
Output:
Though "success" is correctly returned to the browser, the UserTest object is null.
Any thoughts?
Oh and I just noticed this message:
#qtp-1661406123-0] DEBUG ninja.utils.AbstractContext - Not able to parse body because request did not send content type header at: /create_user
After a bit of testing I figured out that the object parsing is not triggered for GET routes. The code should work fine given a route specified by router.POST()... instead of router.GET()...
Currently, I want to get list of selected checkbox from a table.
and I tried to have a sample code as below :
public class Student {
public List<String> listSubject;
public List<String> getListSubject() {
return listSubject;
}
public void setListSubject(List<String> listSubject) {
this.listSubject = listSubject;
}
private int id;
private String name;
private int age;
public boolean single;
public boolean isSingle() {
return single;
}
public void setSingle(boolean single) {
this.single = single;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(List<String> listSubject, int id, String name, int age,
boolean single) {
super();
this.listSubject = listSubject;
this.id = id;
this.name = name;
this.age = age;
this.single = single;
}
}
And the blow is controller
and StudentForm to add information
after selected checkbox from form, I want to display all result to a view :
But until now, I still can't controller adding selected value into a listofSubject which I created for a student.
THe blow is the link of sample code which I am implementing :
https://dl.dropboxusercontent.com/u/11576807/spring-mvc-example.zip
Besides, I want to use a tag instead of submit button to redirect to result page.
And the system only allow user to select two options, at that time, the remain checkbox will be disabled.
Can you please share with me your solution in this case ?
Please tell me know the way to do it with the sample above.
Thanks
You already found the answer. Check stu.getListSubject(). All the checked items will populated to List by Spring MVC.
Your controller should look like this.
#RequestMapping(value = "/student/add", method = RequestMethod.POST)
public String addStudent(Student stu, ModelMap model){
for (String s: stu.getListSubject()) {
//You can see values populated
System.out.println("string: " + s);
}
model.addAttribute("name",stu.getName());
model.addAttribute("age", stu.getAge());
model.addAttribute("single", stu.isSingle());
model.addAttribute("listSubject", stu.getListSubject());
return "studentView";
}
And you have error in your studentView.jsp file.
Instead of this
<c:forEach items="listSubject" var="subject">
<td>${subject}</td>
</c:forEach>
use this:
<c:forEach items="${listSubject}" var="subject">
<td>${subject}</td>
</c:forEach>
You missed ${} .