Root url "/" of the homepagecontroller gives http error 404 - spring

I have defined a controller using:
#Controller
#RequestMapping("/")
public class HomePageController {
#RequestMapping(method = RequestMethod.GET)
public String home(#RequestParam(value = "logout", defaultValue = "false") final boolean logout, final Model model, final RedirectAttributes redirectModel, final HttpServletRequest request, final HttpServletResponse response) {
System.out.println("testing");return "homepage";
}
The control doesnt even come to the home method defined here and gives the response:
HTTP Status 404 – Not Found
However when I change the request mapping to #RequestMapping("/test"), I am able to get control in the home method defined above.
Why am I not able to hit the controller when the request mapping is defined with "/"? I need the root url to land me on the homepage.

Try this
Remove #RequestMapping("/") above HomePageController and add above specific method signature like below
public class HomePageController {
#RequestMapping(method = RequestMethod.GET,path="/")
public String home(#RequestParam(value = "logout", defaultValue = "false")....
}
Should work !

Related

Error 400 when receiving data from URL parameters en Spring MVC

I am trying to receive data from an URL with two parameters like this one:
http://localhost:80000/xxx/xxx/tickets/search?codprovincia=28&municipio=110000
No matter the approach, I am always getting a 400 error, but if I access the URL without the two parameters, the controller returns the view correctly (without the parameters, naturally)
This is the code of my controller:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping("tickets")
public String tickets(Model model, #RequestParam ("codprovincia") String codprovincia, #RequestParam ("municipio") String municipio, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
Extra info: if I use this URL:
http://localhost:9081/xxx/xxx/tickets/search/28/790000
And this code:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping(value = "buscar/{codprovincia}/{municipio}", method = RequestMethod.GET)
public String buscar(#PathVariable Integer codprovincia, #PathVariable Integer municipio ,Model model, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
It gets the parameters correctly. The problem is that I have to use the first URL. I have reviewed similar questions about similar issues, and I have implemented the solutions to those issues, but I get the 400 error regardless what I try (add value="xxx=, required=false, and other suggestions.)
For RequestParam, you need to explicitly add 'name' attribute
#RequestParam(name = "codprovincia"), #RequestParam (name = "municipio")
No need to for HttpServletRequest, unless you have reason
Also, in your 'tickets' method, RequestMapping is not conforming to your URL path.
I think it should be
#RequestMapping("/xxx/tickets/search")
Cheers!

Access absolute path of resource when using #RequestMapping in spring boot controller

I am using #RquestMapping for mapping url to controller method.
#RestController
#RequestMapping(path = "/api/tasks")
public class TaskController { ....
and methods inside controller have /{id} with request mapping annotations.
#RequestMapping(
path = "/{taskId},
method = RequestMethod.GET
)
public Map<String, Object> methodOne(...
I want to access http method and absolute path (configured path) for that method inside.
i.e. I want to get /api/tasks/{taskId} as value (not the /api/tasks/1 if api is called for task id 1) and GET as method inside of the methodOne.
I checked the HandlerMapping but it returns actual path of resource called by client. Not the configured path for the method / resource.
Any help or guidance would be highly appreciated. Thank you.
String[] pathReqMappingAnnotationOnControllerClass = this.getClass().getAnnotation(RequestMapping.class).path();
Method method = TaskApiController.class.getMethod("getListOfTasks", HttpServletRequest.class, HttpServletResponse.class);
String[] pathReqMappingAnnotationOnControllerMethod = method.getAnnotation(RequestMapping.class).path();
String wholePath = pathReqMappingAnnotationOnControllerClass[0] + pathReqMappingAnnotationOnControllerMethod[0];
//pathReqMappingAnnotationOnControllerMethod will be empty array if method is not annotated for path
#RequestMapping(path = "/{id}", method = [RequestMethod.DELETE])
public void test(#PathVariable("id") String id, HttpServletRequest request) {
\\ Code Here
}
In the method parameter, id is the pathVariable. And request method is accessible in the request variable (Although I do not know what is the point as you are limiting it to only accept GET requests)
As suggested by #codedetector, best option is if you have request object or you can add one if you dont have it.
#RequestMapping(path = "/{taskId}, method = RequestMethod.GET)
public String methodOne(HttpServletRequest request){
String test = request.getRequestURI();
return test;
}
If you dont have request object in your method, with below code you can get any URL on your system.
import org.springframework.hateoas.mvc.ControllerLinkBuilder
...
ControllerLinkBuilder linkBuilder = ControllerLinkBuilder.linkTo(methodOn(YourController.class).getSomeEntityMethod(parameterId, parameterTwoId))
URI methodUri = linkBuilder.Uri()
String methodUrl = methodUri.getPath()
--------Edit
I am not sure why you need in this format "/api/tasks/{taskId}" as value (not the /api/tasks/1 )but i can think of using a constant use it for your #RequestMapping path parameter and then easily after getting absolute path , replace/append it with that constant.
String pathParam ="/{taskId}"
#RequestMapping(path = "/{id}", method = [RequestMethod.DELETE])
public void test(#PathVariable("id") String id, HttpServletRequest request) {
switch(id){
case 1:
method1();
break;
case 2:
method2();
break
....
....
}
}
private void method1(){};
private void method2(){};
private void method3(){};

Spring - Inconsistent context path

Spring seems to resolve links in an inconsistent way.
For example, if the current URL is
http://localhost/roles
the following anchor
roleA1
goes to http://localhost/roleA1 instead of http://localhost/roles/roleA1
On the other hand, if the current URL is
http://localhost/roles/ (note the '/' at the end)
the previous link will resolve to http://localhost/roles/roleA1
Both http://localhost/roles and http://localhost/roles/ go to the same page, so Spring treats them equally. Now I would like to avoid using absolute paths but if I leave it as it is now, users navigating to http://localhost/roles will get the wrong behaviour.
Is there a way to fix it?
This is my Controller's configuration:
#RequestMapping("/roles")
public class RoleController {
#RequestMapping(method = RequestMethod.GET)
public String roles(final Map<String, Object> model) {
...
return "roles";
}
#RequestMapping(path = "/{roleId}", method = RequestMethod.GET)
public String role(#PathVariable String roleId, final Map<String, Object> model) {
...
return "role";
}

405 error while using POST method in Spring + google app engine

Whenever I try to use method post I am getting 405 error. The get method is working properly. I tried changing the type by using ajax. but it didn't work. Please help
#Controller
public class PaymentController {
#Autowired
private IAccountService accountService;
#RequestMapping(value = "/payment", method = RequestMethod.POST)
public String returnAccountInformation(HttpSession session, Model model) {
String email = (String) session.getAttribute("email");
PlanInfo planInfo = getAccountService().getPlanInfo(email);
PlanInfoBean planInfoBean = new PlanInfoBean();
planInfoBean.setPlanName(planInfo.getPlanName());
planInfoBean.setPlanType(planInfo.getPlanType());
planInfoBean.setFeatures(planInfo.getFeatures());
model.addAttribute(IPaymentConstants.PLANINFO2, planInfoBean);
// System.out.println(session.getAttribute("email"));
return "AccountDetails";
}

Nested Velocity template with Spring formView

I have a Spring app that I'd like to add a login feature to. I'd like to put the login form in the header of the site. This means that it'll be included on several pages. When defining the controller that the form submits to, what do I specify as the formView?
Is it possible to specify the login template that's included in header (that's included in each head :-)) as the formView?
Thanks for the help. If anything is unclear than I'm happy to provide more details or show code.
Nevermind. I realized that it doesn't matter whether the Velocity template is included in another file. I added this to the template:
<form method="POST">
#springBind("credentials.*")
and my controller looks like this:
#Controller
public class SplashController implements Serializable {
protected final Log logger = LogFactory.getLog(getClass());
private static final long serialVersionUID = 7526471155622776147L;
#ModelAttribute("credentials")
public LoginCredentials getFormBean() {
return new LoginCredentials();
}
#RequestMapping(method = RequestMethod.GET)
public String showForm() {
logger.info("In showForm method of SplashController");
return "splash";
}
#RequestMapping(method = RequestMethod.POST)
public ModelAndView onSubmit(LoginCredentials credentials, BindingResult bindingResult) {
logger.info("In onSubmit method of SplashController");
logger.info("Username = " + credentials.getUsername());
logger.info("Password = " + credentials.getPassword());
ModelAndView modelAndView = new ModelAndView("home");
return modelAndView;
}
}
and it works.

Resources