Spring Model Argument is not enriched by controller mapping - spring-mvc

In a Spring Controller method, I want to enrich the Model elements from what is posted from the jsp file.
Here is the start of the code function.
the model is void everytime the function is entered. Any Hint about that?
#RequestMapping(value = Uris.IMPORTADDRBOOK)
public String mainImportController(HttpServletRequest request, HttpServletResponse response, Model model,
#RequestParam(value = "chosenSP", required = false) String bookToImportName,
#RequestParam(value = "catMode", required = false) String catMode,
#RequestParam(value = "transition", required = false) ImportControllerTransitions transition) {
logger.debug(String.format("controller import. Etat entrée : %s, transition demandée : %s, chosen SP : %s, catmode : %s",
model.asMap().get("importState"), transition, bookToImportName, catMode));
logger.debug(String.format("Modele Entree Import Controller:"));
for (String attribute : model.asMap().keySet())
logger.debug(String.format("%s : %s", attribute, model.asMap().get(attribute)));
if (!model.containsAttribute("importState"))
model.addAttribute("importState", ImportControllerState.INITIAL);
switch ((ImportControllerState) model.asMap().get("importState")) {
case INITIAL:
if (transition == ImportControllerTransitions.CONNECTORCHOICE) {
model.addAttribute("importState", ImportControllerState.CONNECTOR);
if (bookToImportName != null)
model.addAttribute("chosenSP", DynAddrBookTypes.valueOf(bookToImportName));
}
break;
default:
break;
}
logger.debug(String.format("Modele sortie Import Controller:"));
for (String attribute : model.asMap().keySet())
logger.debug(String.format("%s : %s", attribute, model.asMap().get(attribute)));
return Uris.IMPORTADDRBOOK;
}
The JSP can read correctly the model attribute but when I come back into the controller, model is empty again...
Thanks in advance,

Following up on Bart's comments above and answer from Donal Boyle in this related SO question, #SessionAttributes is the right way to keep the values of the model objects despite the fact the Spring MVC server side is stateless.
The code in my question works just fine provided the class declaration include the #SessionAttributes annotation as below :
#Controller
#SessionAttributes({ "importState", "chosenSP", "catMode" })
public class ImportContactController {

Related

Correct way to return different objects on a java spring boot api?

Consider the following code:
#RequestMapping(value = "/somePath")
public ResponseEntity someResource(
#RequestParam(value = "number") int number
) {
switch (number) {
case 1:
return ResponseEntity.badRequest().build();
case 2:
HashMap<String, Object> map = new HashMap<>();
map.put("ok", "but with map");
return ResponseEntity.ok(map);
default:
return ResponseEntity.ok("ok");
}
}
This way I can return custom payloads with different http status, but my IDE keeps me warning: Raw use of parameterized class 'ResponseEntity'. If I define a type, I lose this customization. What is the recommended way of achieving this behavior?
as mentioned in the comments by #jlh91, I was satisfied with ResponseEntity<?> on the main method and for each case, its method would return ResponseEntity<String> or ResponseEntity<Integer>

ASP.NET MVC cannot convert IList to IEnumerable? Also tried with IList to IList and still an error

Trying to create a partial view with ASP.NET MVC and Ajax. However I keep getting an error saying cannot convert IList to IEnumerable.
A class for my web service:
public IList<Courses> GetHallamUniCourses()
{
List <Courses> HallamCourse = new List <Courses>();
foreach(var courselist in _hallamUniProxy.GetAllCourses())
{
_courses = new Courses();
_courses.CourseID = courselist.CourseId;
_courses.CourseName = courselist.CourseName;
_courses.CourseDescription = courselist.CourseDescription;
_courses.EntryRequirements = courselist.EntryCriteria;
HallamCourse.Add(_courses);
}
return HallamCourse();
}
Then on the controller where the error is coming up:
IEnumerable<Courses.Services.Service.SheffieldHallam> courseHallam = _HallamService.GetHallamUniCourses();
Any ideas why this is happening?
Change the controllercode to:
IEnumerable<Courses> courseHallam = _HallamService.GetHallamUniCourses();
Just for fun here is a rewrite i think will do the trick for you, as well as its a little simpler.
public IList<Courses> GetHallamUniCourses()
{
return _hallamUniProxy.GetAllCourses().Select(a=>
new Courses()
{
CourseID = a.CourseId,
CourseName = a.CourseName,
CourseDescription = a.CourseDescription,
EntryRequirements = a.EntryCriteria
}).ToList();
}
But all in all it looks like you are missing some coding concepts. What you say is a "class", is a method (the one I rewrote above). A controller method in ASP.NET MVC usually return some sort of result.
so IEnumerable<Courses.Services.Service.SheffieldHallam> courseHallam = _HallamService.GetHallamUniCourses(); wont do.
Basic intro to a simple MVC controller
//The name of the class must be Name+Controller, and it must extend Controller
class SomeController: Controller{
//This is a method in the controller, it returns a Result
//its URI is http[s]://Domain/Some
public ContentResult Index(){
return Content("Hello");
}
//This is a sub method of controller some, it's URI is http[s]://Domain/Some/Else
public ContentResult Else(){
return Content("Hello");
}
}
so when you say that you get an error on a controller, the interesting part is where in the controller. If i said that i get an error in the controller on the return Content("Hello") then that might not be too descriptive

Spring MVC default GET request parameter binding to command type

As I read explanation here, I found that Spring can automatically bind GET request parameter to a type. Below is the sample code from the link.
#Controller
#RequestMapping("/person")
public class PersonController {
...
#RequestMapping("/create")
public String create(Person p) {
//TODO: add Person to DAO
return "person/show";
}
}
Can someone tell me how spring do this? What bean that contains the logic to convert the parameter onto command type (Person type)?
The trick is done here: org.springframework.web.method.annotation.ModelAttributeMethodProcessor#resolveArgument()
This is the excerpt of code where it actually binds the class to the values:
String name = ModelFactory.getNameForParameter(parameter);
//Here it determines the type of the parameter and creates an instance
Object attribute = (mavContainer.containsAttribute(name)) ?
mavContainer.getModel().get(name) : createAttribute(name, parameter, binderFactory, request);
//Then it binds the parameters from the servlet to the previously created instance
WebDataBinder binder = binderFactory.createBinder(request, attribute, name);
if (binder.getTarget() != null) {
bindRequestParameters(binder, request);
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors()) {
if (isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}
}

Recommended way to display an error message without resorting to #ModelAttribute with Spring MVC

I have the following method skeleton in a Spring MVC application:
#RequestMapping(value = "/activateMember/{token}", method = RequestMethod.GET, produces = "text/html")
public String activateMember(#PathVariable("token") String token) {
...
}
I am trying to display an error message if the token is invalid for some reason. However I have no ModelAttribute in the method arguments and I don't really want one. But of course I can't use an Errors or BindingResults argument because of the absence of a ModelAttribute and its corresponding form.
So my question is:
what is the recommended way to display an error message given the above method signature and without introducing a ModelAttribute?
If the String you've returned from the method is a viewname (Spring default) then simply create a view for this case and do like:
#RequestMapping()
public String activateMember(#PathVariable("token") String token) {
if(checkToken(token)){
doProcess();
return "userprofile";
} else {
return "badtoken"
}
}
In more complicated case you may have a hierarchy of exceptions, related to bad tokens. (Token is expired, token is just incorrect and so on). You can register an #ExceptionHandler in the same controller:
#RequestMapping()
public String activateMember(#PathVariable("token") String token) {
return activate(token); // This method may throw TokenException and subclasses.
}
#ExceptionHandler(TokenException.class)
public ModelAndView tokenException(TokenException e){
// some code
return new ModelAndView("badtoken", "exception", e);
}

How do SOAP headers work in ASMX Web Services?

I have a project that uses an asmx file with [WebMethods] and [SoapHeader("Auth")]. I have no experience using SOAP and don't understand how it works yet.
Going through the code I noticed that you can use a variable with the same name as the header and it contains the data. How is the data sent to the header? Where does it come from?
The data is sent in header by making use of a class that derives from SoapHeader. This class will be declared as a property in your webservice class. Then in your web method you will check the authentication information in this property before processing the actual method.
A simple implementation can be found here http://www.codeproject.com/KB/cpp/authforwebservices.aspx
The following msdn link tells about another similar technique, which would be more sophisticated one http://msdn.microsoft.com/en-us/library/9z52by6a.aspx.
Basic idea behind passing data in header remains same.
The data comes from XML within the <soap:Header> section of the SOAP envelope.
Create a class for your soap header like normal.
public class AuthHeader : SoapHeader
{
public string CompanyID;
public string Username;
public string Password;
}
Then within your normal class had the reference.
public class MyClass : WebService
{
public readonly AuthHeader authHeader;
[SoapHeader("authHeader", Direction = SoapHeaderDirection.In)]
[WebMethod(CacheDuration = 20
, EnableSession = true
, Description = "Find stuff now."
, MessageName = "FindStuff")]
[ScriptMethod(UseHttpGet = false
, ResponseFormat = ResponseFormat.Xml
, XmlSerializeString = true)]
public MyResponseClass FindStuff(string searchString)
{
MyResponseClass myResponseClass = new MyResponseClass();
if (authHeader.Username == "myUser" &&
authHeader.Password == "myPass" &&
authHeader.CompanyID == "BobsTire")
{
....
myResponseClass = ....
}
return myResponseClass;
}
}

Resources