Get URL parameter for crit use Spring MVC Hibernate - spring

I want to be list out all my users with criteria of where id = formId. The code is working but just that it list out all the users instead of being filtered by formId. Please tell me where i did wrongly. Do tell me if you need any more info to solve this!
controller
*url = http://localhost:8080/User/Panda?Id=1
#RequestMapping(value = {"/{name}?Id={id}" }, method = RequestMethod.GET)
public String listClinicUser(ModelMap model, #PathVariable("id") Integer id) {
logger.info("Users List Page - Id = " + id);
List<User> user = service.findAllUsers(id);
model.addAttribute("users", user);
return "user/list";
}
Service
public List<User> findAllUsers(Integer id) {
return dao.findAllUsers(id);
}
DAO Class
public interface UserDao {
List<User> findAllUsers(Integer id);
}
*DAOImpl Class
#SuppressWarnings("unchecked")
public List<User> findAllUsers(Integer id) {
Criteria crit = createEntityCriteria();
crit.add(Restrictions.eq("formId",id));
crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List<User> users = (List<Usert>) crit.list();
return users;
}
*for createEntityCriteria() i created in another class call abstractDao and extends to it.
private final Class<T> persistentClass;
#SuppressWarnings("unchecked")
public AbstractDao(){
this.persistentClass =(Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
protected Criteria createEntityCriteria(){
return getSession().createCriteria(persistentClass);
}
Class Entity
#Entity
#Table(name="USER")
public class User implements Serializable{
#NotEmpty
#Column(name="formId", nullable=false)
private Integer formId;
#NotEmpty
#Column(name="FIRST_NAME", nullable=false)
private String firstName;
#NotEmpty
#Column(name="LAST_NAME", nullable=false)
private String lastName;
public Integer getFormId() {
return formId;
}
public void setFormId(Integer formId) {
this.formId= formId;
}
...
}

value = {"/{name}?Id={id}" }
This is wrong way to extract URL param. If you want to get URL param, you should pass it to your method using #RequestParam annotation:
#RequestMapping(value = {"/{name}" }, method = RequestMethod.GET)
public String listClinicUser(ModelMap model, #RequestParam("Id") Integer id) {
//...
}
Spring automatically pass value that you need. For example in case of ?Id=1 Spring will pass 1 to your controller

In your url /{name} is a path variable and is annotated with #PathVariable like in:
#RequestMapping(value = "/foo/bar/{name}", method = GET)
#ResponseBody
public String getBarByName(#PathVariable String name) { ... }
And ?Id=id is a request parameter and is annotated wiht #RequestParam so if we map to url like this one:
http://localhost:8080/api/foo/bar?id=100
we do it like this
#RequestMapping(value = "/foo/bar", method = GET)
#ResponseBody
public String getBarById(#RequestParam("id") Integer id) { ... }
So to combine them to map to your url:
#RequestMapping(value = {"/{name}" }, params = "id", method = RequestMethod.GET)
public String listClinicUser(ModelMap model, #PathVariable String name, #RequestParam("id" Integer id)) { ... }

Related

Spring boot application I can not get data from oracle database it returns [] in postman

Spring boot application I can not get data from oracle database it returns []. In postman, it returns other requests e.g home method in controller class returns correctly. also, the table created by model class the problem is getting data from the table.
Here is the postman result:
I get this in console:
Model class
#Entity // This tells Hibernate to make a table out of this class
public class Userr {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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;
}
}
//Controller Class
#RestController
public class MainController {
#Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
#PostMapping(path="/add") // Map ONLY POST Requests
public #ResponseBody String addNewUser (#RequestParam String name
, #RequestParam String email) {
// #ResponseBody means the returned String is the response, not a view name
// #RequestParam means it is a parameter from the GET or POST request
Userr n = new Userr();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path="/all")
public #ResponseBody Iterable<Userr> getAllUsers() {
// This returns a JSON or XML with the users
//
return userRepository.findAll();
}
#GetMapping(path="/al")
public List<Userr> printPersonInfo() {
List<Userr> list = new ArrayList<>();
userRepository.findAll().forEach(list::add);
return list;
}
#RequestMapping("/user")
public String home(){
return "PPPPPP";
}
}
//Repository Class
public interface UserRepository extends CrudRepository<Userr, Integer> {
}
Add #Repository annotation to your UserRepository. It will help with your issue.

How to add a new role?

I have a user with admin and user roles, now I need to add ROLE_SUPPORT and restrict this role to only reading the list of users, how can I do this?
public class UserController {
#Autowired
UserService userService;
#RequestMapping(value = "getAll", method = RequestMethod.POST)
public List<User> getUsers() throws IOException {
return userService.getUsers();
}
#PostMapping("save")
#ResponseStatus(HttpStatus.OK)
public void save(#RequestBody User user) {
userService.save(user);
}
#RequestMapping(value = "delete", method = RequestMethod.POST)
public void delete(#RequestBody User user) {
userService.delete(user);
}
#RequestMapping(value = "getUser", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
#ResponseBody
public User getUser(#RequestBody RequestDto requestDto) throws IOException {
return userService.getUser(requestDto.getId());
}
I suppose a new method should be added to this controller, but I could be wrong
public class User extends BaseEntity<Integer> {
public enum Roles {
ADMIN
}
private String firstName;
private String lastName;
#Column(name = "username")
private String username;
#Convert(converter = PurshasedProductConverter.class)
private List<PurshasedProduct> purshasedProducts;
private String email;
private String activationCode;
#Convert(converter = AttachmentConverter.class)
private Attachment userAvatar;
public Attachment getUserAvatar() {
return userAvatar;
}
public void setUserAvatar(Attachment userAvatar) {
this.userAvatar = userAvatar;
}
#JsonProperty(access = Access.WRITE_ONLY)
private String password;
#JsonProperty(access = Access.WRITE_ONLY)
private String temporaryPassword;
#Convert(converter = StringArrayConverter.class)
private String[] roles;
private Date lastPasswordReset;
private Date dateCreated;
private Date dateUpdated;
private Date validatyTime;
private Boolean active;
public User() {
lastPasswordReset = dateCreated = dateUpdated = new Date();
roles = new String[]{"USER"};
}
That is, when requesting with the support role, a list of users should be returned.
Spring-Security provides this support by just adding #PreAuthorize annotation
#RequestMapping(value = "getAll", method = RequestMethod.GET)
**#PreAuthorize("hasRole('ROLE_SUPPORT')")**
public List<User> getUsers() throws IOException {
return userService.getUsers();
}

How to send model property, the property is the model too in spring

I have two models.
#Entity
class Product {
#Id
private String id;
private String name;
#ManyToOne(optional = false)
#JoinColumn(name = "category_id", referencedColumnName = "id")
#NotNull(groups = {CREATE.class, UPDATE.class})
private Category category;
...
}
#Entity
class Category {
#Id
private String id;
private String name;
...
}
#RestController
#RequestMapping(path = "/product")
class ProductController {
#RequestMapping(method = RequestMethod.POST)
public void create(#ModelAttribute Product product) {
...
}
}
I want send request to ProductController:
http POST http://localhost:8080/product name=='Product 1' category=1
The param category is id of Category into db, but spring does not understand it.
Is it possible to do this?
Well, your entitiy classes are ok, but it's really weird to see parameters in the POST request especially in so sort as you have it placed here.
Here is my sample that is working properly
public class Product {
private String id;
private String name;
private Category category;
******
}
public class Category {
private String id;
private String name;
*******
}
#RestController
#RequestMapping(path = "/product")
public class ProductController {
#RequestMapping(method = RequestMethod.POST)
public void create(#ModelAttribute Product product) {
Product prd1 = product;
prd1.getId();
}
}
And just in case here is an appConfig:
#Configuration
#EnableWebMvc
public class AppConfig {
}
That is all. Now your contorller is expecting to get a message that is a Product instance.
Let's go onward. It's pretty weird to see parameters in the POST query. I've had some test and they are ok - just pass the data as a request body! Whatever you cose. For instance let's modify controller as it shown below:
#RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public void create(#ModelAttribute Product product) {
Product prd1 = product;
prd1.getId();
}
}
And now you have to send a POST message with a body that contains a Product data in a JSON format, i.e
{ "id": 1 }
and it works for all other formats that are supported by spring

Spring - Many To One - phonebook assigning contacts to user

I am a newbee in java and spring. My first exercise is project to simulate web phone book. I'm stuck with assigning contact to specific user, and later on displaying contacts for that specific user. Any idea or guideline is appreciated.
User class
#Entity
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String lastName;
private String email;
private String username;
private String password;
#Transient
private String retypePassword;
#ManyToMany(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
#JoinTable(name="users_roles",
joinColumns = {#JoinColumn(name="user_id", referencedColumnName="id")},
inverseJoinColumns = {#JoinColumn(name="role_id", referencedColumnName="roles_id")}
)
private List<Rolee> authorities;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "userForPhonebook")
#Fetch(value = FetchMode.SUBSELECT)
private Collection<Contact> allContacts;
// getters and setters
Contact class
#Entity
public class Contact implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int contactID;
private String name;
private String lastName;
private String email;
private String areaCode;
private String telNumber;
private String adress;
private String city;
private String note;
private String contactImage;
#JoinColumn(name = "users_id")
#ManyToOne(fetch = FetchType.EAGER, optional = false)
private User userForPhonebook;
// getters and setters
ContactServiceImpl class
#Service
public class ContactServiceImpl implements ContactService {
#Autowired
private ContactDAO contactDAO;
#Autowired
private UserDAO userDAO;
#Autowired
private ServletContext context;
#Override
public void addContact(ContactModel contactModel, MultipartFile[] contactImages, User user) {
Contact contact = new Contact();
/*
creating contact
*/
User user2 = userDAO.userGetById(user.getId()); //<-- i cant get user id
contact.setUserForPhonebook(user2);
// --------------------------------
User u = new User(); //
u.setId(2); // hard coding users id...
contact.setUserForPhonebook(u); // and its working fine
// rest of code to create contact ...
UserDAOImpl
// ...
#Override
public void addUser(User user) {
Session s = getCurrentSession();
Transaction trans = s.beginTransaction();
getCurrentSession().save(user);
trans.commit();
}
// ...
UserServiceImpl
// ...
#Override
public void addUser(UserModel userModel) {
User user = new User();
// creating user ...
getUserDAO().addUser(user);
}
// ...
RegisterController
// ...
#RequestMapping(value = "/addUser", method = RequestMethod.POST)
public String postRegister(#Valid #ModelAttribute("newUser") UserModel userModel, BindingResult results, ModelMap model) {
if (results.hasErrors()) {
return "addUser";
}
// checking if username, email exist in database ...
// password matching
getUserService().addUser(user);
return "index";
}
// ...
ContactController
// ...
#RequestMapping(value = "/addContact", method = RequestMethod.POST)
public String postAddContact(#Valid #ModelAttribute("addContact") ContactModel contactModel, BindingResult results, HttpServletRequest request, #RequestParam("contactImages") MultipartFile[] contactImages, User user)
throws FileNotFoundException, IOException {
if (results.hasErrors()) {
return "addContact";
}
getContactService().addContact(contactModel, contactImages, user);
return "redirect:phoneBook";
}
//...
You are not specifying how Spring is supposed to bind your User object in your postAddContact signature.
#RequestMapping(value = "/addContact", method = RequestMethod.POST)
public String postAddContact(
// Ok, this is a model retrieved from request params
#Valid #ModelAttribute("addContact") ContactModel contactModel,
// Ok, a BindingResult is mapped when the validation above occurs
BindingResult results,
// Ok, bind the internal HttlServletRequest
HttpServletRequest request,
// Ok, bind this to the multipart part of the request
#RequestParam("contactImages") MultipartFile[] contactImages,
// ... no idea how to bind this
User user)
throws FileNotFoundException, IOException {
// ...
}
You need to specify yourself which user is going to get the contact.
You could add the field inside your ContactModel object, like userId, and in your controller retrieve that user from database before adding the contact.
ContactController.java
// ...
#RequestMapping(value = "/addContact", method = RequestMethod.POST)
public String postAddContact(#Valid #ModelAttribute("addContact") ContactModel contactModel, BindingResult results, HttpServletRequest request, #RequestParam("contactImages") MultipartFile[] contactImages)
throws FileNotFoundException, IOException {
if (results.hasErrors()) {
return "addContact";
}
// Retrieve the user
User user = getUserService().retrieveUser(contactModel.getUserId());
getContactService().addContact(contactModel, contactImages, user);
return "redirect:phoneBook";
}
//...
You could also add a path variable, use the connected user, etc. Above code is just a suggestion.
The answer here helped me to assign currently active user to contact and my postAddContact looks like this. Sorry if I didn't correctly ask the question and I hope this will help someone else
#RequestMapping(value = "/addContact", method = RequestMethod.POST)
public String postAddContact(#Valid #ModelAttribute("addContact") ContactModel contactModel, BindingResult results, HttpServletRequest request, #RequestParam("contactImages") MultipartFile[] contactImages)
throws FileNotFoundException, IOException {
if (results.hasErrors()) {
return "addContact";
}
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetail = (UserDetails) auth.getPrincipal();
User u = userDAO.getUserByUsername(userDetail.getUsername());
request.getSession().setAttribute("id", u.getId());
int userId = (int) request.getSession().getAttribute("id");
User user = new User();
user.setId(userId);
getContactService().addContact(contactModel, contactImages, user);
return "redirect:phoneBook";
}

Handle Spring REST separated Frontend/backend post request

I'm trying to develop a RESTful webservice with Spring using 2 different projects for backend/webservice and frontend.
In the backend project I implemented the model
#Entity
#Table(name="user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_user", nullable = false)
private String id;
#Column(name = "username", nullable = false)
private String username;
#Column(name = "firstname", nullable = false)
private String firstname;
#Column(name = "lastname", nullable = false)
private String lastname;
#Column(name = "password", nullable = false)
private String password;
#Column(name = "email", nullable = false)
private String email;
#Column(name = "own_printer", nullable = false)
private Boolean ownsPrinter;
// Getters Setters...
}
There is also a UserDAO class to access database (through Hibernate 4) and a UserManager for business processes. And then a UserController:
#RestController
public class UserController {
private UserService userService ;
#RequestMapping(value = "/listusers")
List<User> getAllUser() {
Application.context = new ClassPathXmlApplicationContext("applicationContext.xml");
userService = (UserService) Application.context.getBean("userService");
List<User> users = userService.getUsers();
return users;
}
#RequestMapping(value = "/user/{userid}")
User getUserById(#PathVariable("userid") String userId) {
Application.context = new ClassPathXmlApplicationContext("applicationContext.xml");
userService = (UserService) Application.context.getBean("userService");
User user = userService.getUserById(userId);
return user;
}
#RequestMapping(value = "/user/add")
#ResponseBody
User signUpUser(#RequestBody User user ) {
// Don't really know what to do...
userService = (UserService) Application.context.getBean("userService");
return user;
}
}
And now for the frontend projects I implemented the same User class. And I wrote a UserDAO UserManager and UserController classes:
//UserDAO.java
#Repository("userDAO")
public class UserDAOImpl implements UserDAO{
#Override
public ArrayList<User> getUsers() {
//User[] users = new RestTemplate().getForEntity(WebService.getWebServiceUrl() + "users", User[].class).getBody();
ArrayList<User> user = new RestTemplate().getForEntity(WebService.getWebServiceUrl() + "listusers", ArrayList.class).getBody();
return (user);
//return Arrays.asList(users);
}
#Override
public User getUserById(String userId) {
User user = new RestTemplate().getForEntity(WebService.getWebServiceUrl() + "user/" + userId, User.class).getBody();
return user;
}
#Override
public void insertUser(User user) {
// doesn't work
RestTemplate template = new RestTempl ate();
template.postForObject(WebService.getWebServiceUrl() + "user/add",user, String.class);
System.out.println(user.toString());
}
}
//UserController.java
#Controller
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
private UserService userService = new UserServiceImpl();
#RequestMapping(value = "/listusers", method = RequestMethod.GET)
public String listUsers(#RequestParam(required=false)Locale locale, Model model) {
logger.info("Users page", locale);
ArrayList<User> users = userService.getUsers();
model.addAttribute("users", users);
return "listusers";
}
#RequestMapping(value = "/user/{user_id}", method = RequestMethod.GET)
public String singleUser(#RequestParam(required=false)Locale locale,
Model model,HttpServletRequest request, #RequestParam String id) {
logger.info("User page", locale);
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "user";
}
#RequestMapping(value = "/signup", method = RequestMethod.GET)
public String listPersons(Model model) {
model.addAttribute("user", new User());
return "signup";
}
//For add and update person both
#RequestMapping(value= "/user/add", method = RequestMethod.POST)
#ResponseBody
public void saveUser(Model model, #ModelAttribute("user") User u){
RestTemplate rt = new RestTemplate();
rt.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
rt.getMessageConverters().add(new StringHttpMessageConverter());
String uri = new String(WebService.getWebServiceUrl() + "user/add");
User user = new User();
user = u;
User returns = rt.postForObject(uri, u, User.class);
}
}
The get requests work: I get to display my list of users. But my problem is that I can't get to pass data from the frontend part to the backend webservice part with a post request... I'have been trying several solutions but I think there is something wrong with something else.
I'm kinda new in the world of JavaEE applications. Can someone help me or guide me to a solution ?
In the Frontend UserDAO:
public ArrayList<User> getUsers() {
ArrayList<User> user = new RestTemplate().getForEntity(WebService.getWebServiceUrl() + "listusers", ArrayList.class).getBody();
return (user);
}
This code allows to request the server through the uri "/listuser". On the frontEnd UserController you can see the function that call getUsers():
#RequestMapping(value = "/listusers", method = RequestMethod.GET)
public String listUsers(#RequestParam(required=false)Locale locale, Model model) {
logger.info("Users page", locale);
ArrayList<User> users = userService.getUsers();
model.addAttribute("users", users);
return "listusers";
}
And then in the backend the function that route this url:
#RequestMapping(value = "/listusers")
List<User> getAllUser() {
Application.context = new ClassPathXmlApplicationContext("applicationContext.xml");
userService = (UserService) Application.context.getBean("userService");
List<User> users = userService.getUsers();
return users;
}
After this, teh backend UserDAO class access to database.
You may want to take a look at the URL you are posting to at the frontend. You are using the same URL for posting to frontend (UserDAO) and backend (UserController) : WebService.getWebServiceUrl()
[EDIT]
You have two POST services as /user/add/ , If you are exposing them on the same url, it is a conflict. Probably your backend will be hosted on another port or another server. You should use that url to hit the backend service from frontend.
[EDIT 2]
Yes for listusers you are not making a REST call from frontend. You are calling the JAVA API userService. But for add user, you are making a REST call from frontend to backend once again

Resources