Spring MVC Annotated Controller - java

I have a controller which has a few actions, which are triggered by hitting various buttons on the page. I would like to have a default action, but am unsure how to annotate the method. Here is an example:
#Controller
#RequestMapping("/view.jsp")
public class ExampleController {
#RequestMapping(method = RequestMethod.GET)
public ModelAndView displayResults() {
ModelAndView mav = new ModelAndView("view");
mav.addObject("queryResults", methodToQueryDBForListing());
return mav;
}
#RequestMapping(method = RequestMethod.POST, params="submit=Action 1")
public ModelAndView action1(#RequestParam("selectedItemKey") String key) {
ModelAndView mav = new ModelAndView("action1");
//Business logic
return mav;
}
#RequestMapping(method = RequestMethod.POST, params="submit=Action 2")
public ModelAndView action2(#RequestParam("selectedItemKey") String key) {
ModelAndView mav = new ModelAndView("action2");
//Business logic
return mav;
}
//A few more methods which basically do what action1 and action2 do
}
How can I annotate a method which will act on a POST with any submit button pressed with no key selected?
I have tried:
#RequestMethod(method = RequestMethod.POST, params="!selectedItemKey")
#RequestMethod(method = RequestMethod.POST)
I'd really hate it if I had to set required = false on each of the methods which take RequestParams and then conditionally check to see if one comes in or not... Is there a way to annotate this to work properly?

I would make this a path variable rather than a parameter, and would get rid of the .jsp:
#RequestMapping("/view")
...
#RequestMapping("/action1")
#RequestMapping("/action2")
#RequestMapping("/{action}")
It is more "restful".

The proper annotation is:
#RequestMapping(
method = RequestMethod.POST,
params = { "!selectedItemKey", "submit" }
)
It seems odd though, that it was not hitting this method until adding that second parameter.

I'm not so familiar with annotated spring-mvc but I can remember that when extending a MultiActionController you can specify a default entry point by defining the following spring config:
<bean name="myController"
class="foo.bar.MyController">
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="defaultMethodName" value="init" />
</bean>
</property>
package foo.bar
public class MyController extends MultiActionController {
/**
* Called when no parameter was passed.
*/
public ModelAndView init(HttpServletRequest request,
HttpServletResponse response) {
return new ModelAndView("myDefaultView");
}
/**
* action=method1
*/
public void method1(HttpServletRequest request,
HttpServletResponse response) {
return new ModelAndView("method1");
}
/**
* action=method2
*/
public void method2(HttpServletRequest request,
HttpServletResponse response) {
return new ModelAndView("method2");
}
}
So maybe in this instance you could solve this by configuring your controller over spring config instead of using annotations.

Related

Is there a way to intercept the result of Spring MVC RestController endpoint before serialization?

My Spring RestController have the following method which returns the DTO:
#RequestMapping(
value = "/profile",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public UserProfileDto getUserProfile() {...}
I would like intercept the controller method call, get the resulted DTO and modify some fieds before serialization into JSON?
As far as I understand there are 2 ways:
Custom filter:
Doesn't work as I can get only byte stream of serialized response
Custom HandlerInterceptor:
But I'm not sure how can I do it as postHandle in HandlerInterceptor have null ModelAndView, and afterCompletion doesn't have ModelAndView at all
You may use OncePerRequestFilter, like this example below,
#Component
public class MyFilter extends OncePerRequestFilter {
private final ObjectMapper objectMapper;
#Autowired
public MyFilter(final ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
#Override
protected void doFilterInternal(
final HttpServletRequest request,
final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException {
// Add your code here ...
}
filterChain.doFilter(request, response);
}
}
You can do this to change the handle your response,
#RequestMapping(
value = "/profile",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<UserProfileDto> getUserProfile() {
return ResponseEntity.ok().body(new UserProfileDto());
}

Spring changed session values

In Spring application, I need to hold user value until I don't remove or destroy.
According to it, I have used the HttpSession in the Controller as follows
#Controller
public class MyController {
#RequestMapping(value = { "/search" }, method = RequestMethod.POST) //this hander called once
public String search(SearchVo aSearchVo, BindingResult result,
ModelMap model,HttpSession httpsession) {
if (result.hasErrors()) {
model.addAttribute("searches", new SearchVo());
return "home";
}
httpSession.setAttribute("searchstring", aSearchVo.getSearchString());
return "caseResult";
}
#SuppressWarnings("unchecked")
#RequestMapping(value = { "/filtersearch" }, method = RequestMethod.POST) //This handler call again and again
public String filterSearch(#ModelAttribute("filter") FilterVo fvo,ModelMap model , HttpSession httpSession){
String searchKeyWorld=httpSession.getAttribute("searchstring");
System.out.println(searchKeyWorld);
searchKeyWorld+=fvo.getFilterWorld();
return "caseResult";
}
}
but in the session variable, the value gets changed automatically as in the last filter; as I haven't set any session variable in filtersearch Handler
You need to use #SessionAttributes for putting variable in http session.
This is a class level annoation.
#Controller
#SessionAttributes("searches")
public class MyController{
#RequestMapping(value = { "/search" }, method = RequestMethod.POST) //this hander called once
public String search(SearchVo aSearchVo, BindingResult result,
ModelMap model,WebRequest webRequest) {
if (result.hasErrors()) {
model.addAttribute("searches", new SearchVo());
return "home";
}
model.addAttribute("searches", new SearchVo());
//For removing anything from session
//webRequest.removeAttribute("searches", WebRequest.SCOPE_SESSION);
return "caseResult";
}
}

Is it possible in Spring MVC to have void handlers for requests?

Is it possible in Spring MVC to have void handler for request?
Suppose I have a simple controller, which doesn't need to interact with any view.
#Controller
#RequestMapping("/cursor")
public class CursorController {
#RequestMapping(value = "/{id}", method = PUT)
public void setter(#PathVariable("id") int id) {
AnswerController.setCursor(id);
}
}
UPD
#Controller
#RequestMapping("/cursor")
public class CursorController {
#RequestMapping(value = "/{id}", method = PUT)
public ResponseEntity<String> update(#PathVariable("id") int id) {
AnswerController.setCursor(id);
return new ResponseEntity<String>(HttpStatus.NO_CONTENT);
}
}
you can return void, then you have to mark the method with
#ResponseStatus(value = HttpStatus.OK) you don't need #ResponseBody
#RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.OK)
public void defaultMethod(...) {
...
}
Only get methods return a 200 status code implicity, all others you have do one of three things:
Return void and mark the method with #ResponseStatus(value = HttpStatus.OK)
Return An object and mark it with #ResponseBody
Return an HttpEntity instance
Also refer this for interesting information.

defining default url for controller spring mvc3

I am new to spring mvc3 development and was facing a minor issue (which I was didn't face with ASP.Net MVC3). I want to know the process of defining a default (or landing) URL for a controller.
I have an accounts controller where I do all account management related stuff. So all my urls are mapped to this controller. I want to know that how can I map my "/accounts" url request to hit openAccountsDashboard method?
Code -
.... imports...
#Controller
#RequestMapping(value = "/accounts/*")
public class AccountController {
#RequestMapping( value = "/", method = RequestMethod.GET)
public ModelAndView openAccountsDashboard(HttpServletRequest request) {
.....
return new ModelAndView("accounts/landing");
}
#RequestMapping( value = "/change-password", method = RequestMethod.GET)
public ModelAndView openPasswordChangePage(HttpServletRequest request) {
.....
return new ModelAndView("accounts/passwordChange");
}
... other actions...
}
Any help would be great!
Thanks
Try something like this:
.... imports...
#Controller
#RequestMapping(value = "/accounts/")
public class AccountController {
#RequestMapping( value = "", method = RequestMethod.GET)
public ModelAndView openAccountsDashboard(HttpServletRequest request) {
.....
return new ModelAndView("accounts/landing");
}
#RequestMapping( value = "/change-password", method = RequestMethod.GET)
public ModelAndView openPasswordChangePage(HttpServletRequest request) {
.....
return new ModelAndView("accounts/passwordChange");
}
... other actions...
}
Then you can use url like this:
http://localhost:8080/yourwebapp/accounts/
to hit openAccountsDashboard method.
Regards,
Arek

Using MultiActionController

Currently i am using paging on my page which uses MultiActionController which displays a jsp page perfectly , on the same page now i want to validate a simple textfield (input/form:input) also want to retrieve name and id from a dropdown(Select option) once a link is clicked. Simple !!
Two questions
Can i use a class implements Validator? and inject it same way as simpleformcontroller in config or some other way within the controller? How? example please?
Can i use java bean in jsp -> i always get error of binding, how to indicated controller to use this bean? i have have passed as argument to my method add and also tried overriding newCommandObject
Controller.java
public ModelAndView add(HttpServletRequest request, HttpServletResponse response, Person person) throws Exception {
return new ModelAndView("userpage");
}
#Override
protected Object newCommandObject(Class clazz)
throws Exception {
return new Person();
}
I will do something like below in Spring version > 2.5
#Controller
public class YourController
{
protected final Log logger = LogFactory.getLog(getClass());
private final String yourInputJsp = "yourInputJsp";
private final String yourInputJspSuccess = "yourInputJspSuccess";
private YourService yourService;
#Autowired
#Qualifier("yourFormValidator")
private YourFormValidator validator;
#RequestMapping(value = "/yourRequest.htm", method = RequestMethod.GET)
public String referenceData(ModelMap model, HttpServletRequest request) throws Exception
{
yourService = new YourServiceImpl(ContextHandler.getWebAppContext(request));
YourFormData yourFormData = new YourFormData();
model.addAttribute("yourFormData", yourFormData);
return yourInputJsp;
}
#InitBinder()
public void initBinder(WebDataBinder binder) throws Exception {
binder.registerCustomEditor(String.class, new StringMultipartFileEditor());
}
#RequestMapping(value="/yourRequest.htm", method = RequestMethod.POST)
public String process(#ModelAttribute("yourFormData") YourFormData yourFormData, BindingResult result, SessionStatus status, HttpServletRequest request)
{
String mav = yourInputJsp;
validator.validate(yourFormData, result);
if(!result.hasErrors())
{
//Some business logic
mav = "redirect:yourInputJspSuccess.htm";
status.setComplete();
}
return mav;
}
}

Categories

Resources