Spring MVC routing to wrong controller - java

I have a web application in SpringMVC, After login I want to point it to "/" but its always pointing me to /home.
<security:form-login
login-page="/home/login"
default-target-url="/"
always-use-default-target="true"
authentication-failure-url="/auth/failed"/>
here is homecontroller.java
#Controller
#RequestMapping(value = "/")
#SessionAttributes({"loginModel"})
public class HomeController {
#Autowired
private LoginModelService loginModelService;
#RequestMapping(method = RequestMethod.GET)
public String loadHome(Model model, Principal principal) {
model.addAttribute("loginModel", loginModelService.getLoginModelByUserLoginName(principal.getName()));
return "index";
}
#RequestMapping(method = RequestMethod.GET, value = "/home")
public String showHome(Model model, Principal principal) {
model.addAttribute("loginModel", loginModelService.getLoginModelByUserLoginName(principal.getName()));
return "system/home";
}
}
After login showHome method is being called instead of loadHome

Related

Spring #RestController with #RequestBody #Valid by default

Usually we write
#RestController
public class TestController {
#RequestMapping(value = "/test")
public String test2(#RequestBody #Valid TestClass req) {
return "test2";
}
}
But since it is a REST controller is it possible to configure Spring to use #RequestBody #Valid by default, so these annotations could be omitted?

How do I clear ModelMap session?

I have this annotation at the top of my controller:
#SessionAttributes("user")
And this mapping:
#RequestMapping(value="/logout", method = RequestMethod.GET)
public String logout(ModelMap model){
model.clear();
But when I navigate to that URL it's still able to retrieve the User session attributes..
How do I properly clear the ModelMap value?
Looks like I need this signature instead w/ SessionStatus:
#RequestMapping(value="/logout", method = RequestMethod.GET)
public String logout(SessionStatus status){
status.setComplete();
return "redirect:/";
}

Spring Boot - Save User between Controller Methods

What's the best approach to avoid repeating the same userService DB lookup over and over again in my controller methods?
I'm using Spring Boot 1.5.2 with spring-boot-starter-security and spring-boot-starter-thymeleaf for templating.
I tried adding an instance variable for SecurityContextHolder.getContext().getAuthentication() but it gave me a NullPointerException.
#Controller
public class DashboardController {
#Autowired
private UserService userService;
#Value("${product.name}")
private String productName;
#RequestMapping(value="/dashboard", method = RequestMethod.GET)
public ModelAndView home() {
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
modelAndView.addObject("email", user.getEmail());
modelAndView.setViewName("dashboard");
return modelAndView;
}
#RequestMapping(value="/dashboard/faq", method = RequestMethod.GET)
public ModelAndView faq(){
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
modelAndView.addObject("email", user.getEmail());
modelAndView.addObject("productname", productName);
modelAndView.setViewName("faq");
return modelAndView;
}
If you want to get at the user that is stored in the session, you can use this annotation:
#RequestMapping("/me")
public User me(#AuthenticationPrincipal User user) {
return user;
}
If you then want the user to always be available in thymeleaf I would use a #ControllerAdvice
#ControllerAdvice(annotations = Controller.class)
public class GlobalVariablesControllerAdvice {
#ModelAttribute("user")
public User user() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = null;
// get user from authentication, but make sure to check for nulls
return user;
}
}

how to disable spring security authentication on just a few methods

I have spring basic authentication implemented, but there are a few urls which I don't want to be authenticated. For example, http://www.mywebsite.com/rest/signUp
How to I make this unauthenticated?
#Transactional
#RequestMapping(value = "/signUp", headers = "Accept=application/json", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public #ResponseBody String signUp(#RequestParam("user_name") String login,
#RequestParam("pass_word") String passWord,
#RequestParam("first_name") String firstName,
#RequestParam("last_name") String lastName,
#RequestParam("network_name") String networkName,
#RequestParam("email") String email) {
if(!userDAO.loginExists(login)) {
User user = new User();
user.setLogin(login);
user.setFirstName(firstName);
user.setLastName(lastName);
user.setNetworkName(networkName);
user.setEmail(email);
user.setPassword(passWord);
sessionFactory.getCurrentSession().save(user);
return json("success");
}
return json("failure");
}
<http>
<intercept-url pattern="/rest/signUp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<!-- your other interceptor-url elements -->
</http>
Add an intercept-url pattern for your signup service which is authenticated anonymously.

CGLib Proxy for Integer (Final class) in Spring MVC

I need such a usage:
For each request I want to inject userId into DemoController But because of being a final class without empty constructor I can not inject it. What is the best practice in such cases? A service with request scope is fine?
#Configuration
public class CityFactory{
#Bean(name = {"currentUserId")
#Scope(value = WebApplicationContext.SCOPE_REQUEST,proxyMode = ScopedProxyMode.TARGET_CLASS)
#Autowired
public Integer getUserId(HttpServletRequest request) {
return UserUtil.getCurrentUserId(request.getServerName());
}
}
#RequestMapping("/demo")
#Controller
public class DemoController {
#Autowired
Ingeter userId;
#RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)
public ModelAndView helloWorld(#PathVariable("name") String name, Model model) {
Map<String, Object> myModel = new HashMap<String, Object>();
model.addAttribute("user", userId);
return new ModelAndView("v3/test", "m", model);
}
}
Your best bet is to create an explicit class called UserId, which in turn contains an integer. Not only will this play nicer with CGLIB's proxying, it also clarifies your design.
You can use Supplier or Provider
#Configuration
public class CityFactory{
#Bean
#Autowired
public Supplier<Integer> getUserId(HttpServletRequest request) {
return () -> UserUtil.getCurrentUserId(request.getServerName());
}
}
#RequestMapping("/demo")
#Controller
public class DemoController {
#Autowired
Supplier<Ingeter> getUserId;

Categories