Get attribute from current page - spring

TaskController
#GetMapping("/admin/addTask")
public String task(String email, Model model, HttpSession session){
session.setAttribute("email",email);
model.addAttribute("task",new Task());
return "task";
}
#PostMapping("/admin/addTask")
public String addTask(#Valid Task task, BindingResult bindingResult,HttpSession session){
if(bindingResult.hasErrors()){
return "task";
}
String emailik = (String) session.getAttribute("email");
taskService.addTask(task,userService.findOne(emailik));
return "redirect:/admin/users";
}
#GetMapping("/admin/usertask")
public String getEmail(User email, Model model,HttpSession session){
model.addAttribute("task",taskService.findUserTask(email));
model.addAttribute("emaail",session.getAttribute("email"));
return "usertasklist";
}
users list controller
#GetMapping("admin/users")
public String listUsers(Model model, #RequestParam(defaultValue = "") String name) {
model.addAttribute("users",userService.findByName(name));
return "list";
}
}
when i enter user in admin/users i get link like /admin/usertask?email=rafs#gmail.com where is users tasks
and i want this work with it
<div th:each="email:${emaail}">
<a th:href="#{/admin/addTask(email=${email})}" class="btn btn-dark"></a>
</div>
but with getattribute it is displayed just after adding task
is there any way to get this email?

If you want to get the email in usertaks endpoint /admin/usertask?email=rafs#gmail.com
You need to change your controller like this
#GetMapping("/admin/usertask")
public String getEmail(#RequestParam("email") String email, Model model,HttpSession session){
model.addAttribute("task",taskService.findUserTask(email));
model.addAttribute("emaail",session.getAttribute("email"));
return "usertasklist";
}

Related

How to redirect from one controller method to another method with model data in spring boot application

In this example I am trying to redirect from handleSaveContact() controller method from contactSuccessMsg() controller method but after transfer I need to display success or update or failure msg to the UI which is only possible if I transfer Model data from 1st method to 2nd.
Could any one please suggest me how I can trasfer model data from one controller method to another controller method.
#GetMapping(value={"/", "/loadForm"})
public String loadContactForm(Model model) {
model.addAttribute("contact", new Contact());
return "index";
}
#PostMapping("/saveContact")
public String handleSaveContact(Contact contact, Model model) {
String msgTxt = null;
if(contact.getContactId()==null) {
msgTxt = "Contact Saved Successfully..!!";
}else {
msgTxt = "Contact Updated Successfully..!!";
}
contact.setIsActive("Y");
boolean isSaved = contactService.saveContact(contact);
if(isSaved) {
model.addAttribute("successMsg", msgTxt);
}else {
model.addAttribute("errorMsg", "Failed To Save Contact..!!");
}
return "redirect:/contactSuccessMsg";
}
/**
* To resolve Double Posting problem, redirecting the post req method to get request.
* #param contact
* #param model
* #return
*/
#GetMapping(value="/contactSuccessMsg")
public String contactSuccessMsg(Model model) {
model.addAttribute("contact", new Contact());
return "index";
}
I used Spring 3.2.3
1.)Added RedirectAttributes redirectAttributes to the method parameter list in controller1.
public String controlMapping1(
#ModelAttribute("mapping1Form") final Object mapping1FormObject,
final BindingResult mapping1BindingResult,
final Model model,
final RedirectAttributes redirectAttributes)
Inside the method added code to add flash attribute to redirectAttributes
redirectAttributes.addFlashAttribute("mapping1Form", mapping1FormObject);
Then, in the second contoller use method parameter annotated with #ModelAttribute to access redirect Attributes :
#ModelAttribute("mapping1Form") final Object mapping1FormObject
Here is the sample code from Controller 1:
#RequestMapping(value = { "/mapping1" }, method = RequestMethod.POST)
public String controlMapping1(
#ModelAttribute("mapping1Form") final Object mapping1FormObject,
final BindingResult mapping1BindingResult,
final Model model,
final RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("mapping1Form", mapping1FormObject);
return "redirect:mapping2";
}
From Contoller 2:
#RequestMapping(value = "/mapping2", method = RequestMethod.GET)
public String controlMapping2(
#ModelAttribute("mapping1Form") final Object mapping1FormObject,
final BindingResult mapping1BindingResult,
final Model model) {
model.addAttribute("transformationForm", mapping1FormObject);
return "new/view";
}

spring CRUD DELETE action that return viewmodel or empty body

I want to write a DELETE action that return a no content body if no id error exist. If id not exist I want to redirect to the coresponding GET view.
Controller code:
#RequestMapping(value = "/todo/delete/{id}", method = RequestMethod.GET)
public String getDeleteTodo(Model model, #PathVariable("id") String id)
{
Optional<Todo> todo = todoRepository.findById(Long.decode(id));
if (todo.isEmpty()) {
model.addAttribute("msginfo", "ctl-todo.delete.msginfo.id-not-exist");
model.addAttribute("requestedId", id);
}
else {
model.addAttribute("todo", todo.get());
}
return "v-todo-delete";
}
#RequestMapping(value = "/todo/delete/{id}", method = RequestMethod.DELETE)
public String deleteTodo(#PathVariable String id, RedirectAttributes redirAttrs)
{
boolean exists = todoRepository.existsById(Long.decode(id));
if (exists) {
todoRepository.deleteById(Long.decode(id));
return ""; //here I want to return a no-content body response
}
else {
redirAttrs.addFlashAttribute("msginfo", "ctl-todo.delete.msginfo.id-not-exist");
redirAttrs.addFlashAttribute("requestedId", id);
return "redirect:/todo/delete" + id;
}
}
More informations about the view:
The GET view is juste a view that display the todo entity corresponding to the id. The deletion is make with a button using ajax to call the DELETE method. Then response is return as 204 with no content into the body, i redirect the user with javascript to the main page... If an id not exist in the DELETE method, I want to redirect to the GET method to show an error message.
If someone have an idea to do this.
Thanks in advance.
Try using return type as ResponseEntity with whatever response body along with a response status. Please refer below code changes:
#RequestMapping(value = "/todo/delete/{id}", method = RequestMethod.DELETE)
public ResponseEntity deleteTodo(#PathVariable String id, RedirectAttributes redirAttrs)
{
boolean exists = todoRepository.existsById(Long.decode(id));
if (exists) {
todoRepository.deleteById(Long.decode(id));
return new ResponseEntity(HttpStatus.NO_CONTENT); //This will return No Content status
}
else {
redirAttrs.addFlashAttribute("msginfo", "ctl-todo.delete.msginfo.id-not-exist");
redirAttrs.addFlashAttribute("requestedId", id);
return new ResponseEntity( "redirect:/todo/delete" + id, HttpStatus.OK);
}
}
Final anwser for me:
#RequestMapping(value = "/todo/delete/{id}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteTodo(#PathVariable String id, RedirectAttributes redirAttrs)
{
boolean exists = todoRepository.existsById(Long.decode(id));
if (exists) {
todoRepository.deleteById(Long.decode(id));
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
else {
redirAttrs.addFlashAttribute("msginfo", "ctl-todo.delete.msginfo.id-not-exist");
redirAttrs.addFlashAttribute("requestedId", id);
/* I use CONFLICT here to explain that the entity was possibly deleted
by another user between the moment the user give the view containing
the DELETE ajax link and the moment he click on it. */
return new ResponseEntity<String>( "redirect:/todo/delete" + id, HttpStatus.CONFLICT);
}
}
Thank you Mandar Dharurkar & Jeethesh Kotian for your help ;)

How to pass model data from one controller to another controller spring

I have my controller-A class like this:
#PostMapping("/otp")
public String otpSubmit(#RequestParam("token") String token, HttpSession session, Model model) throws IOException {
Long enrollment = (Long) session.getAttribute("enrollment");
BaseResponse otpResponse = otpRestClient.validateOTP(enrollment, token);
if(otpResponse.getCode().equals("1020")) {
model.addAttribute("object", otpResponse.getPayload());
return "redirect:/password";
}
model.addAttribute("errorCode", otpResponse.getCode());
model.addAttribute("errorMessage", otpResponse.getMessage());
return "/otp";
}
What I want is simple (I think) pass the model.addAttribute("object", otpResponse.getPayload()); to controller-B class so I can access that data in the other view.
How can I inject this into controller-B class?.
By adding redirectAttributes we can pass model data
Here is the Controller one.
public String controlMapping1(
#ModelAttribute("mapping1Form") final Model model,
final RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("mapping1Form", model);
return "redirect:mapping2";
}
Here is Controller2
public String controlMapping2(
#ModelAttribute("mapping1Form") final Model model) {
model.addAttribute("transformationForm", model);
return "view_name";
}
you can save this "Object o = otpResponse.getPayload()" object in a global variable so later you can access it from any controller.

Sending user to a new page after submission

After submitting a new Episode entity I need my user to be sent back to the dashboard - ie /dashboard
I have tried
return /dashboard
but that simply sent the template to the browser without any data.
My controller looks like this:
public class formController {
private EpisodeRepository episodeRepository;
#Autowired
public void setEpisodeRepository(EpisodeRepository episodeRepository) {
this.episodeRepository = episodeRepository;
}
#GetMapping("/newEpisode")
public String episodeForm(Model model) {
model.addAttribute("episode", new Episode());
return "episode";
}
#PostMapping("/newEpisode")
public String episodeSubmit(#ModelAttribute Episode episode) {
episodeRepository.save(episode);
return "dashboard";
}
#GetMapping("/dashboard")
public String dashboard(Model model) {
List<Episode>listEpisodes = new ArrayList<>();
episodeRepository.findAll().forEach((episode) -> {
listEpisodes.add(episode);
});
System.out.println(listEpisodes.size());
model.addAttribute("episodes", listEpisodes);
return "dashboard";
}
#GetMapping("/event/{eventno}")
public String findEvent(#PathVariable String eventno, Model model) {
Episode episode = new Episode();
episode = episodeRepository.findByeventno(eventno);
System.out.println("Printing the values held in episode for one get: " +eventno);
model.addAttribute("episode", episode);
return "episode";
}
}
And the relevant part of the html
<form id="form" class="form-horizontal" method="post" action="#" th:action="#{/newEpisode}" th:object="${episode}">
And the answer is:
#PostMapping("newEpisode")
public String episodeSubmit(#ModelAttribute Episode episode) {
episodeRepository.save(episode);
return "redirect:/dashboard";
}

create two method for same url pattern with different arguments

I have scenario where one url "serachUser" may come with two different value (request parameter) userId or UserName.
so for this I have created two methods
public String searchUserById(#RequestParam long userID, Model model)
public ModelAndView searchUserByName(#RequestParam String userName)
But i am getting Ambiguous mapping found exception. Can Spring handle this situation?
You can use the params parameter to filter by HTTP parameters. In your case it would be something like:
#RequestMapping(value = "/searchUser", params = "userID")
public String searchUserById(#RequestParam long userID, Model model) {
// ...
}
#RequestMapping(value = "/searchUser", params = "userName")
public ModelAndView searchUserByName(#RequestParam String userName) {
// ...
}
Any way incase of request param null is allowed if you don't pass any value it will be null then you can write your coad like:
#RequestMapping(value = "/searchUser", params = {"userID","userName"})
public String searchUserById(#RequestParam long userID,#RequestParam String
userName,
Model model) {
if(userID != null){
//..
}else{
// ...
}

Resources