Springdoc cannot detect POJO's fields to map as individual parameters on UI - spring-boot

My springboot application has a #RestController which takes a POJO class as parameter.
#GetMapping(path="/")
public void sayHello(Person person) {
System.out.println(person);
}
and here's the definition of Person class which is just a POJO.
public class Person {
private String firstName;
private String lastName;
private int age;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + "]";
}
}
This is how springdoc-ui interprets it for showing parameters in UI.
I did not use #RequestBody in the controller yet springdoc assumes the input to be in the form of JSON body. I intend it to be as query parameters as below
Interestingly if I change the swagger implementation to springfox, each fields of the POJO is interpreted as individual parameters in the UI by default. The last screenshot was taken using springfox implemntation. How do I get the same behavior with springdoc?

Using #ParameterObject fixes this.
#GetMapping(path="/")
public void sayHello(#ParameterObject Person person) {
System.out.println(person);
}
Found the solution here:
https://github.com/springdoc/springdoc-openapi/issues/162
https://github.com/springdoc/springdoc-openapi/pull/505

Related

Return an empty object Java Spring Boot REST

I'm writing a dto class containing the information of a user
public class User {
private String firstName;
private String lastName;
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;
}
}
I'd receive this JSON object if I do GET api/v1/user/1
{
firstName: John,
lastName: Kennedy
}
But when the firstName and the lastName are null, I want to receive an empty object like:
{}
How would you do technically on Spring Boot in order to receive such empty object in Json format?
Thank you in advance
You could try to annotate your class with:
#JsonInclude(Include.NON_NULL)
If you want an empty object { } and empty request is not valid for you, you can create an auxiliar class called EmptyObject or something similar:
#JsonSerialize
public class EmptyObject {
}
And into your controller:
return user.getFirstName() == null && user.getLastName() == null ?
ResponseEntity.ok(new EmptyObject()) : ResponseEntity.ok(user);

java 8 streams filter by list over list

I need to filter condition by firstname and lastname in the List of names present in either official or unOfficial names List and return List of EmployeeDetails.
Below are the pojo classes
public class EmployeeDetails {
private NameDetails nameDetails;
public NameDetails getNameDetails() {
return nameDetails;
}
public void setNameDetails(NameDetails nameDetails) {
this.nameDetails = nameDetails;
}
}
public class NameDetails {
private List<Name> officalName;
private List<Name> unOfficialName;
public List<Name> getOfficalName() {
return officalName;
}
public void setOfficalName(List<Name> offiicalName) {
this.officalName = offiicalName;
}
public List<Name> getUnOfficialName() {
return unOfficialName;
}
public void setUnOfficialName(List<Name> unOfficialName) {
this.unOfficialName = unOfficialName;
}
}
public class Name {
private String firstName;
private String lastName;
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;
}
}
I tried for filtering with list of officialNames and it is working fine,but I also want to filter names present in unOfficial Names also.(OR Condition)
return employeeDetailList.stream().filter(employeeDetails->(employeeDetails.getNameDetails().getOffiicalName()).stream()
.anyMatch(name-> (null!=name) && (firstName).equals(name.getFirstName()) && (lastName).equals(name.getLastName())))
.collect(Collectors.toList());
Help me to solve the issue.Thanks
If you can't override equals/hashCode (if you could there would be a faster way), then:
employeeDetailList
.stream()
.filter(x -> Stream.concat(
x.getNameDetails().getOfficalName().stream(),
x.getNameDetails().getUnOfficialName().stream()
)
.anyMatch(y -> Objects.equals(y.getFirstName(), firstName) &&
Objects.equals(y.getLastName(), lastName)))
.collect(Collectors.toList());
Just add the OR condition:
return employeeDetailList.stream().filter(employeeDetails->
((employeeDetails.getNameDetails().getOffiicalName()).stream().anyMatch(name-> (null!=name) && (firstName).equals(name.getFirstName()) && (lastName).equals(name.getLastName()))))
|| ((employeeDetails.getNameDetails().getUnOfficialName()).stream().anyMatch(name-> (null!=name) && (firstName).equals(name.getFirstName()) && (lastName).equals(name.getLastName()))))
.collect(Collectors.toList());

How can I get multiple properties from a Java POJO using the Java 8 Stream API?

Given this class written in the Java 8 style, I wanted to see if I dont need to call the stream api twice :
import java.util.*;
public class Foo {
public static void main(String... args) {
List<Person> persons = new ArrayList<>();
init(persons, Person::new, "John", "Doe");
persons.stream()
.map(Person::getFirstName)
.forEach(System.out::println);
persons.stream()
.map(Person::getLastName)
.forEach(System.out::println);
}
#FunctionalInterface
interface PersonFactory {
Person create(String firstName, String lastName);
}
private static void init(List<Person> persons, PersonFactory factory, String fn, String ln) {
persons.add(factory.create(fn, ln));
}
}
class Person {
private final String firstName;
private final String lastName;
public Person(String fName, String lName) {
this.firstName = fName;
this.lastName = lName;
}
public String getFirstName() {return this.firstName;}
public String getLastName() {return this.lastName;}
}
I wanted to see if I could instead stream the "persons" List in one go.
Any suggestions ?
If you don't need to transform object to another, you can try this
persons.forEach(i -> System.out.println(i.getFirstName() + " " + i.getLastName()));
i think it could be helpfull for you using Map
Map<String, String> mapp = persons.stream().collect(HashMap::new,
(m, c) ->{
m.put(c.getFirstname(), "");
m.put(c.getLastname(), "");
},HashMap::putAll);
System.out.println(mapp.keySet().toString());

javax.el.PropertyNotFoundException: Property 'UserName' not found

I have written a program to display some details entered in one form in another.Like I have a UserRegisteration.jsp where I am entering few details and UserAccount.jsp which has to display some of the entered details.I have created a model object UserDetails which has all the details of a particular code.
When I am running the project I am getting the propertynotfound exception.I have checked everything and couldn't find the reason behind it.I have the getters and setters methods in my model class.And using auto-binding feature using #modelattribute.Kindly let me know if I missed any code.
UserDetails.java
package com.bindu.myBankcontroller;
import java.util.ArrayList;
public class UserDetails {
private String UserName;
private String FirstName;
private String LastName;
private String EmailId;
private ArrayList<String> AccountType;
private ArrayList<String> gender;
private Long AccountNo;
private int age;
private String password;
Address address;
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getEmailId() {
return EmailId;
}
public void setEmailId(String emailId) {
EmailId = emailId;
}
public ArrayList<String> getAccountType() {
return AccountType;
}
public void setAccountType(ArrayList<String> accountType) {
AccountType = accountType;
}
public ArrayList<String> getGender() {
return gender;
}
public void setGender(ArrayList<String> gender) {
this.gender = gender;
}
public Long getAccountNo() {
return AccountNo;
}
public void setAccountNo(Long accountNo) {
AccountNo = accountNo;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Controller class,UserAccountController.java
package com.bindu.myBankcontroller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.*;
import org.springframework.web.servlet.ModelAndView;
import com.bindu.myBankcontroller.UserDetails;
#Controller
public class UserAccountController {
#ModelAttribute
public void addingCommonObjects(Model model1) {
model1.addAttribute("headerMessage", "MyBank, India");
}
#RequestMapping(value="/LoginForm.html", method = RequestMethod.GET)
public ModelAndView getAdmissionForm() {
ModelAndView model1 = new ModelAndView("LoginForm");
return model1;
}
#RequestMapping(value="/userRegistration.html", method = RequestMethod.GET)
public ModelAndView submitRegistrationForm() {
ModelAndView model1 = new ModelAndView("UserRegistration");
return model1;
}
#RequestMapping(value="/UserAccount.html", method = RequestMethod.POST)
public ModelAndView userAccountForm(#ModelAttribute("user") UserDetails user) {
System.out.println("User name:"+user.getUserName());
ModelAndView model1 = new ModelAndView("UserAccount");
return model1;
}
}
UserAccount.jsp
<html>
<body>
<h1>${headerMessage}</h1>
<h3>Congratulations!! you have successfully registered</h3>
<h2>Details submitted by you:: </h2>
<table>
<tr>
<td>User Name :</td>
<td>${user.UserName}</td>
</tr>
<tr>
<td>First Name :</td>
<td>${user.FirstName}</td>
</tr>
<tr>
<td>Last Name :</td>
<td>${user.LastName}</td>
</tr>
</table>
</body>
</html>
None of the related posts helped me in resolving this issue, so I have posted this one.
The problem is cause by the way you are accessing your property in jsp,
${user.UserName}
should instead be
${user.userName}
Same for the other expressions, you should lower case the first letter.
Behind the scenes the UserDetails is introspected and a map of properties is created, but the keys are based on your getter/setter methods, so lowercased (userName, firstName, lastName). In your JSP EL you're passing the key, and it is not matching any property on account of case difference
Your instance variables do not respect the java naming principles. Java variables should start with lower letter and use camel case capitalization.
Ex: userName, firstName, lastName,
and the corresponding getters would be getUserName(), getFirstName(), getLastName().
If you have the instance variable defined like this the jsp accessors will be obtained by stripping the get (or is, if the method returns a boolean) suffix and lower the first letter of the remaining method name: ${user.userName}, ${user.firstName}, ${user.lastName}.

invalid hex number ora-01465

i have this query in my code. i am trying to isert a image into table in the last column(blob). it is showing invalid hex number. can anybody help me out of this?
#ManagedBean(name="userprofile",eager=true)
#SessionScoped
public class Profile {
#ManagedProperty("#{jdbcTemplate}")
public JdbcTemplate jdbcTemplate;
private String firstName,lastName,email,description;
private UploadedFile photo1;
private int contactNumber;
private String insertQry;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public UploadedFile getPhoto1() {
return photo1;
}
public void setPhoto1(UploadedFile photo1) {
this.photo1 = photo1;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
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 int getContactNumber() {
return contactNumber;
}
public void setContactNumber(int contactNumber) {
this.contactNumber = contactNumber;
}
public void insertProfile() throws Exception{
InputStream is=photo1.getInputstream();
System.out.println(is);
insertQry="insert into profile
values('"+getFirstName()+"','"+getLastName()+"','"+getContactNumber()+"',
'"+getEmail()+"','"+getDescription()+"','"+utl_raw.cast_to_raw(is)+"')";
System.out.println(insertQry);
int num=jdbcTemplate.update(insertQry);
System.out.println(num);
}
}
any kind of response is appreciated in advance.
This error:
invalid hex number ora-01465
means that your not sending an Hexa.
Solution:
Please try to convert InputStream to Hexa before insert image.

Resources