Cant get Request Parameter from view to controller Spring MVC - spring-mvc

can anyone help me. I cant understand, why #RequestParameter or request.getParameter() not working.
My controller:
#Controller
public class CheatController extends WebMvcConfigurerAdapter {
#RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello(#RequestParam("gg") String gg, Model model) {
return "hello";
}
}
And my view:
<html>
<body>
<form action="#" th:action="#{/hello}" method="get">
<input type="text" id="gg" name="gg" placeholder="Your data"/>
<input type="submit"/>
</form>
<span th:if="${gg != null}" th:text="${gg}">Static summary</span>
</body>
</html>

Seems like you have an error in the #RequestParam
Try replacing this line public String hello(#RequestParam("gg") String gg, Model model) by:
public String hello(#RequestParam(required = false, defaultValue = "") String gg, Model model)
What we're setting in the line above is that gg is not required and if your param gg comes empty or null the defaultValue will be "". You can remove this options but is a good way to test that the Controller is working, and if you know for sure that you're going to receive always a gg param you can remove it.

You should be using POST instead of GET on your form:
<form action="#" th:action="#{/hello}" method="get">
You can also simplify your controller code to:
#Controller
public class CheatController {
#GetMapping("/hello")
public String hello(#RequestParam("gg") String gg,
Model model) {
...
return "hello";
}
}

I cant understand how it influenced on getting and sending params, but it helped me(i commented that peace of code and it started working). Can anyone explain why it happened?
#Configuration
public class DefaultView extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers( ViewControllerRegistry registry ) {
//registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/all").setViewName("all");
registry.setOrder( Ordered.HIGHEST_PRECEDENCE );
super.addViewControllers( registry );
}
}

Related

I have a View with three form tags. How do I go about processing each form separately in the controller?

I am new to MVC and am having trouble with a more complicated form than most examples, that I've seen.
The View is structured in three sections, which are actually forms.
My question is about passing a model and processing of these forms.
A colleague of mine suggested using three controllers for each form.
But then how do I pass a separate model to each form?
I think you get the idea.
Would you please help me with this task?
Let say we have 3 models
Public class Model1
{
public string name{get;set;}
}
Public class Model2
{
public string name{get;set;}
}
Public class Model3
{
public string name{get;set;}
}
Then we have a three form in a view. and each form corresponds to their own ActionMethod that you specify in the first parameter in Html.BeginForm
#Html.BeginForm("Model1Action","ControllerName",FormMethod.Post)
{
//dont use #Model.Name in the name property of input element.
<input type="text" name="name"/>
}
#Html.BeginForm("Model12Action","ControllerName",FormMethod.Post)
{
//dont use #Model.Name in the name property of input element.
<input type="text" name="name"/>
}
#Html.BeginForm("Model3Action","ControllerName",FormMethod.Post)
{
//dont use #Model.Name in the name property of input element.
<input type="text" name="name"/>
}
Then in the controller Action method
[HttpPost]
Public ActionResult Model1Action(Model1 obj)
{
Response.Write(obj.name);
}
[HttpPost]
Public ActionResult Model1Action(Model1 obj)
{
Response.Write(obj.name);
}
[HttpPost]
Public ActionResult Model1Action(Model1 obj)
{
Response.Write(obj.name);
}

Getting null values in Spring MVC controller when submitting data from the jsp

I have a jsp form with an input box, a domain object with get/set methods, and a controller. When I submit the form I get null values in the controller. The "set" method is never being called in the domain object when i submit the form but the object itself is being called.
Order.jsp
<portlet:defineObjects />
<portlet:actionURL portletMode="view" var="createNewOrderURL">
<portlet:param name="action" value="createNewOrder" />
</portlet:actionURL>
<div>
<form:form name="form" method="post" commandName="refOrder" action="${createNewOrderURL}" id="createOrder">
TestName : ${refOrder.name}<br/> <!-- here I get the correct value to display -->
<form:input path="referenceNum" />
<input type="submit" value="Submit" />
</form:form>
</div>
Order.java
public class Order {
private String name = "Name1";
private String referenceNum;
public Order(){
System.out.println("Inside Order.java");
System.out.println(getReferenceNum());
}
public Order(String name, String referenceNum) {
this.name = name;
this.referenceNum = referenceNum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getReferenceNum() {
return referenceNum;
}
public void setReferenceNum(String referenceNum) {
this.referenceNum = referenceNum;
}
SalesOrderController.java
#RenderMapping
public String defaultRender(RenderRequest request, RenderResponse response, Model model) throws SQLException, NamingException{
model.addAttribute("refOrder",new Order());
return "SalesOrderEntry";
}
#ActionMapping(params={"action=createNewOrder"})
public void addNewOrder(ActionRequest request, ActionResponse response, #ModelAttribute("refOrder") Order order)throws NamingException, SQLException{
System.out.println("Inside addNewOrder method");
System.out.println("New Order is --> "+order.toString());
System.out.println("RefNum - "+order.getReferenceNum());
System.out.println("request.getParameter is "+request.getParameter("referenceNum"));
}
I get null for all the print statements in the controller. Have been trying to fix this for two days now and I can't find what's wrong. Would really appreciate if someone can help me get this to work.
Do you have the following in your src/main/webapp/WEB-INF/liferay-portlet.xml descriptor?
<requires-namespaced-parameters>false</requires-namespaced-parameters>
Also, you might want to take a look at the PortletMVC4Spring project, which is the successor to Spring Portlet MVC. The GitHub project contains archetypes that work in Apache Pluto and Liferay Portal. The requires-namespaced-parameters config option is conveniently set in the archetypes.

Configure multiple controllers in Spring MVC, and call one controller's method from another controller

I am trying to configure multiple controller in my application and also trying to redirect from one controller to other.
Error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'nc' bean method.
EDIT :
First Controller
#Controller
#RequestMapping(value = "/nc")
public class StockController {
#RequestMapping(value = "/testMap", method = RequestMethod.GET)
public String redirectToStockList(#RequestParam(value = "testInput") String testInput) {
System.out.println("In StockController..!!");
return "SampleTamplate";
}
}
Second Controller
#Controller
public class WelcomeController {
#Autowired
private UsersServiceImpl serviceImpl;
private String redirectedURL;
private static final Logger logger = LoggerFactory
.getLogger(WelcomeController.class);
#RequestMapping(value = { "/", "/login" }, method = RequestMethod.GET)
public String login(#RequestParam(value = "username") String username) {
logger.debug("In login() method.");
System.out.println("In WelcomeController..!!");
return "Login";
}
}
jsp:
First Form:
<form action="testMap" method="post">
<input type="text" class="form-control" name="testInput"/>
</form>
Second Form:
<form action="login" method="post">
<input type="text" class="form-control" name="username"/>
</form>
When I submit both forms one by one, control goes to 'WelcomeController' every time. And for first form, It gives 'resources not found' error that's OK because there is no mapping present as "/testMap" in welcome controller.
So what I want is, to call specific controller on my form submission and also call one controller's method from another controller.
Any help would be appreciated.
I will try to answer this question in both Grails and Spring way as this is the best time to introduce Grails here.
In spring when call is leaving from controller then RequestDispatcher actually helps to catch the call or to check the exact view resolver. Now, as you want to transfer call to another controller here sping provides API (http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-redirecting) Inshort you have to use view name like "forward:controllerName" like
#RequestMapping({"/someurl"})
public String execute(Model model) {
if (someCondition) {
return "forward:/someUrlA";
} else {
return "forward:/someUrlB";
}
In grails there is forward method you can find in controller API which does things for you (http://grails.github.io/grails-doc/2.0.4/api/org/codehaus/groovy/grails/plugins/web/api/ControllersApi.html). It actually passes the same session to next requested controller.
Request you to please try to use it. Hope this help.
In the below example the LoginController redirects to the /menu URL if there are validation errors upon submitting a login form by calling the menuMapping() method that resides within the MenuController class.
(NOTE: I have included the use of the BindingResult class and a hypothetical form as this would be a valid reason for wanting to redirect to another controller. However, below solution would still work as well without the BindingResult and if statement without the use of a form).
#Controller
public class LoginController {
MenuController menuController;
#RequestMapping(value = "/login")
public String loginMapping(BindingResult result){
if(result.hasErrors) {
return "login";
}
else {
return menuController.menuMapping();
}
}
With your MenuController in another class like so:
#Controller
public class MenuController {
#RequestMapping(value = "/menu")
public String menuMapping(){
return "menu";
}
}
(EDIT: if you wanted to apply the redirect and the controller methods were within the same class then the loginMapping return statement would simply be return menuMapping(); rather than return menuController.menuMapping();

Spring 3.1 Form binding with List<Date>

I have a form object
public class TestForm {
private long id;
private List<Date> dates;
// getters and setters for the above
}
And my controller has the following..
#RequestMapping(value = "/assignDummy", method = RequestMethod.POST)
public #ResponseBody
String assignDates(TestForm frm) {
System.out.println("frm:"+frm.getId()+", date:"+frm.getDates());
return "Everything is fine";
}
My form..
<form name="abc" method="post" action="assignDummy.htm">
<input type="text" name="id" value="1000">
<input type="text" name="dates[0]" value="4500000">
<input type="submit">
</form>
I get the following error..
Failed to convert property value of type 'java.lang.String' to
required type 'java.util.Date' for property 'dates[0]'; nested
exception is
org.springframework.core.convert.ConversionFailedException: Failed to
convert from type java.lang.String to type java.util.Date for value
'4500000'; nested exception is java.lang.IllegalArgumentException"
Any help is appreciated.
Thanks in advance
You are trying to put a String into Date without converting it, so it crashes.
You have to use a custom property editor in order to convert the input String into a Date.
Try to add in your controller
#InitBinder
public void initBinder(WebDataBinder binder) {
CustomDateEditor editor = new CustomDateEditor(new SimpleDateFormat("MM/dd/yyyy"), true);
binder.registerCustomEditor(Date.class, editor);
}

How to pass complex type using json to ASP.NET MVC controller

I have a View that allows a user to enter/edit data for a new Widget. I'd like to form up that data into a json object and send it to my controller via AJAX so I can do the validation on the server without a postback.
I've got it all working, except I can't figure out how to pass the data so my controller method can accept a complex Widget type instead of individual parameters for each property.
So, if this is my object:
public class Widget
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
I'd like my controller method to look something like this:
public JsonResult Save(Widget widget)
{
...
}
Currently, my jQuery looks like this:
var formData = $("#Form1").serializeArray();
$.post("/Widget/Save",
formData,
function(result){}, "json");
My form (Form1) has an input field for each property on the Widget (Id, Name, Price). This works great, but it ultimately passes each property of the Widget as a separate parameter to my controller method.
Is there a way I could "intercept" the data, maybe using an ActionFilterAttribute, and deserialize it to a Widget object before my controller method gets called?
Thanks Jeff, that got me on the right path. The DefaultModelBinder is smart enough to do all the magic for me...my problem was in my Widget type. In my haste, my type was defined as:
public class Widget
{
public int Id;
public string Name;
public decimal Price;
}
Notice that the type has public fields instead of public properties. Once I changed those to properties, it worked. Here's the final source code that works correctly:
Widget.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Widget.aspx.cs" Inherits="MvcAjaxApp2.Views.Home.Widget" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<script src="../../Scripts/jquery-1.2.6.js" type="text/javascript"></script>
<script type="text/javascript">
function SaveWidget()
{
var formData = $("#Form1").serializeArray();
$.post("/Home/SaveWidget",
formData,
function(data){
alert(data.Result);
}, "json");
}
</script>
<form id="Form1">
<input type="hidden" name="widget.Id" value="1" />
<input type="text" name="widget.Name" value="my widget" />
<input type="text" name="widget.Price" value="5.43" />
<input type="button" value="Save" onclick="SaveWidget()" />
</form>
</asp:Content>
HomeController.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
namespace MvcAjaxApp2.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
ViewData["Title"] = "About Page";
return View();
}
public ActionResult Widget()
{
ViewData["Title"] = "Widget";
return View();
}
public JsonResult SaveWidget(Widget widget)
{
// Save the Widget
return Json(new { Result = String.Format("Saved widget: '{0}' for ${1}", widget.Name, widget.Price) });
}
}
public class Widget
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
}
Note that (in MrDustpan's solution) the parameter name widget in the MVC Action method must match with the prefix used in the name attribute in the ASPX file.
If this is not the case then the Action method will always receive a null object.
<input type="text" name="widget.Text" value="Hello" /> - OK
<input type="text" name="mywidget.Text" value="Hello" /> - FAILS
Phil Haack has a good blog post about model binding that might be helpful. Not 100% what you're talking about here, but I think it might give you a better overall understand about the DefaultModelBinder.
What you want to do is structure your javascript form object in the same way your backend object is structured:
{ Id : "id", Name : "name", Price : 1.0 }
Then use the toJSON plugin to convert it into the above string. You send this string to your backend and use something like the JayRock libraries to convert it to a new Widget object.

Resources