I have a method where I require the argument name and I have it set as a session attribute as it will be fixed through out the session. However, I have trouble adding it to the function. Any help is appreciated.
LoginController class that sets the session attribute
#Controller
#SessionAttributes({"name", "date"})
public class LoginController {
#Autowired
LoginService service;
/*
* Map /login to this method
* localhost:8080/spring-mvc/login
* spring-mvc -> dispatcher (todo-servlet.xml)
* dispatcher detects login url
* dispatcher use view resolver to find .jsp file based on String. In this case, login
* view resolver locates login.jsp and shows the content to user via http
*/
#RequestMapping(value = "/test")
// Mark this method as an actual repsonse back to user
#ResponseBody
public String test() {
return "Hello, world!";
}
#RequestMapping(value ="/")
public String returnLogin() {
return "redirect:/loginPage";
}
// Only handles get request from the login page
#RequestMapping(value = "/login", method= RequestMethod.GET)
public String loginPage() {
// search through the view resolver for login.jsp
return "login";
}
// Only handles post request from the login page
#RequestMapping(value = "/login", method= RequestMethod.POST)
// #RequestParm to be used for user input
// Model is used to supply attributes to views
// ModelMap has the same functionality has model except it has an addition function where it allows a collection of attributes
public String handleLogin(#RequestParam String name, #RequestParam String password, ModelMap model) {
if (service.validateUser(name, password)) {
// Send name to .jsp
// use addAttrible( nameAtJSP, nameInRequestParam ) to check for null
model.addAttribute("name", name);
model.addAttribute("passWelcome", password);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String date = sdf.format(new Date());
model.addAttribute("date", date);
}
else {
model.put("errorMessage","Invalid credentials");
return loginPage();
}
return "welcome";
}
My controller class. I've commented the part that I need to add the session attribute.
#Controller
public class ToDoController {
#Autowired
private ToDoService service;
#RequestMapping(value = "/list-todo", method= RequestMethod.GET)
public String showToDo(ModelMap model, String name, String date) {
model.addAttribute("toDos", service.retrieveTodos("in28Minutes"));
model.addAttribute("name", name);
model.addAttribute("date", date);
// Only returns to the jsp
return "list-todos";
}
#RequestMapping(value = "/add-todo", method= RequestMethod.GET)
public String addToDo() {
return "addToDo";
}
#RequestMapping(value = "/add-todo", method= RequestMethod.POST)
public String addToDo(ModelMap model,#RequestParam String description) {
// SESSION ATTRIBUTE NAME
model.addAttribute("name");
service.addTodo((String) model.get("name"), description, new Date(), false);
model.clear();
return "redirect:/list-todo";
}
#SessionAttributes doesn't do what you are trying to achieve.
From javadoc of #SessionAttributes:
NOTE: Session attributes as indicated using this annotation correspond
to a specific handler's model attributes, getting transparently stored
in a conversational session. Those attributes will be removed once the
handler indicates completion of its conversational session. Therefore,
use this facility for such conversational attributes which are
supposed to be stored in the session temporarily during the course of
a specific handler's conversation.
For permanent session attributes, e.g. a user authentication object,
use the traditional session.setAttribute method instead.
So, what you need to do is:
public String handleLogin(#RequestParam String name,
#RequestParam String password,
ModelMap model,
HttpSession httpSession) {
// your code here
httpSession.setAttribute("name", name);
// your code here
}
And then you can retrieve this session attribute in your ToDoController as httpSession.getAttribute("name");
Related
I am using Spring MVC. I do the following steps
Login into my application
delete browser cookies and cache
do a refresh
When I delete browser cookies and do a refresh it redirects me to the login page. But this login page is opened in the response of the API (in developers console) and not the actual browser.
I want to open the login page in the browser, how do I do that ?
/**
* Handles requests related to security of the application.
*/
#Controller
public class SecurityController {
#Resource(name = "syncService")
private SyncService syncService;
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(ModelMap model , HttpServletResponse res) {
res.setHeader("URL", "Login");
return "login";
}
#RequestMapping(value = "/403", method = RequestMethod.GET)
public String acd(ModelMap model) {
return "403";
}
#RequestMapping(value = "/next", method = RequestMethod.GET)
public String next(ModelMap model) {
return "next";
}
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public String logout(ModelMap model, HttpServletRequest request) {
HttpSession session = request.getSession();
session.invalidate();
/* model.addAttribute("mess","you have been logged out"); */
return "login";
}
#RequestMapping(value = "/accessdenied", method = RequestMethod.GET)
public String loginerror(ModelMap model) {
model.addAttribute("error", "true");
return "denied";
}
}
I had one login controller in that I define one session variable, now I want to access that session variable in all my remaining controllers in my application?
this is my login controller code snippet
#RequestMapping(value = "/login", method = RequestMethod.POST,produces = "application/json")
public #ResponseBody Map<String, String> validateUser(#RequestBody String loginParameters,HttpServletRequest request) throws Exception {
try{
HttpSession session=request.getSession();
JSONObject json = new JSONObject(loginParameters.trim());
String un=json.getString("username");
session.setAttribute("username", un);
This is my ProfileController code snippet
#Controller
public class ProfileController {
#RequestMapping(value = "/getUserData", method = RequestMethod.GET,produces = "application/json")
public #ResponseBody Map<String, String> getUser(HttpServletRequest req) throws Exception {
try{
HttpSession session=req.getSession();
String loggedInUser=(String)session.getAttribute("username");
System.out.println("UserName is "+ loggedInUser);
Now I want to access this session variable(username) in my another profile controller. I tried like this but I got null pointer expection in ProfileController.
I found the solution to my requirement.
actually, my requirement is to access the session value from the login controller to profile controller.
So What I did is instead of accessing the session variable in profile controller, just I am calling a method in login controller that will return my required value.
#Controller
public class LoginController {
private HttpSession session=null;
#RequestMapping(value = "/login", method = RequestMethod.POST,produces = "application/json")
public #ResponseBody Map<String, String> validateUser(#RequestBody String loginParameters,HttpServletRequest request) throws Exception {
try{
session=request.getSession();
JSONObject json = new JSONObject(loginParameters.trim());
String un=json.getString("username");
session.setAttribute("username", un);
}catch(Exception e)
{
}
}
public String getUserName()
{
return session.getAttribute("username");
}
}
ProfileController
#Controller
public class ProfileController {
#Autowired
private LoginController loginControllerObj;
#RequestMapping(value = "/getUserData", method = RequestMethod.GET,produces = "application/json")
public #ResponseBody Map<String, String> getUser(HttpServletRequest req) throws Exception {
try{
String loggedInUser=loginControllerObj.getUserName();
System.out.println("UserName is "+ loggedInUser);
As per my understanding, in my question. I got null pointer exception in Profile controller this is because of if we want to access the session then we need to call the request.getSession()
the method that will return if any session is associated with the request then it will return that one if not then it creates a new session.the same concept in my profile controller also applied.
Instead of accessing the existing session in will create the new session because of both are two different requests.
For this reason, I follow the above code get rid of my requirement.
if it is about current logged in username then you just pass Principal parameter to controller method.
#RequestMapping(value="/login", method = RequestMethod.GET)
public String methodName(ModelMap model, Principal principal ) {
String name = principal.getName(); //get logged in username
model.addAttribute("username", name);
return "page";
}
I have a Spring application and below is a Controller method I have to resolve the /login. And I found this code from another application, but I cannot get it to work properly in my application.
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(HttpSession session, ModelMap modelMap, Model model,
#RequestParam("userName") String userName,
#RequestParam("password") String password, HttpServletRequest req)
throws IOException, SessionException {
String page = "home";
String sessionId = session.getId();
modelMap.addAttribute("sessionId", sessionId);
page = "redirect:/home";
return page;
}
So basically it will redirect to the /home
below is the controller to resolve /home
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(HttpSession session,Locale locale, Model model, #RequestParam(value = "segment", required = false) String segment,
#ModelAttribute("sessionId") String sessionId) throws SessionException {
System.out.println("sessionId : " + sessionId); // this `sessionId` is empty
return "home";
}
But the issue is the sessionId is empty when I try to print that. But I can get it from the HttpSession session.
What is the reason for this, why the #ModelAttribute("sessionId") String sessionId did not get populated with the value though I'm adding it to the ModalMap.
I am working on a Spring mvc application in which I have to display a list of locations. I have a controller method for location. Following is my controller method code:
#RequestMapping("/location")
public class LocationController {
#RequestMapping(value = "/home")
public String showAllLocations(ModelMap modelMap) {
logger.info("showAllLocations() begins:");
try {
List<LocationModel> locationList = locationService
.getAllLocations("");
modelMap.addAttribute("locationlist", locationList);
} catch (Exception e) {
logger.debug("Error while getting locations: " + e.getMessage());
e.printStackTrace();
}
return "LocationHome";
}
}
It works fine when I user following URL:
http://www.example.com:8080/myapp/location/home
But when I use http://www.example.com:8080/myapp/location, it shows error.
How can I view location list without using 'home', by following URL:
http://www.example.com:8080/myapp/location
#RequestMapping(value = "/home")
public String doHome(ModelMap modelMap) {
...
}
#RequestMapping(value = "/**")
public String doDefault(ModelMap modelMap) {
...
}
Make sure you put more specific request handler before less specific one.
#RequestMapping(value = "/", method = { RequestMethod.GET, RequestMethod.POST })
This can map you to a default handler.
You have the request mapping for the LocationController here ,
#RequestMapping("/location")
public class LocationController {..}
So all the URL to be intercepted by this controller should have the pattern /location followed by the method request mapping as here ,
#RequestMapping(value = "/home")
public String showAllLocations(ModelMap modelMap) {..}
If you need to intercept the request for http://www.example.com:8080/myapp/location . Just remove the url mapping from the controller and assign it to the method.
I have noticed the following code is redirecting the User to a URL inside the project,
#RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "yahoo.com";
return "redirect:" + redirectUrl;
}
whereas, the following is redirecting properly as intended, but requires http:// or https://
#RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = "http://www.yahoo.com";
return "redirect:" + redirectUrl;
}
I want the redirect to always redirect to the URL specified, whether it has a valid protocol in it or not and do not want to redirect to a view. How can I do that?
Thanks,
You can do it with two ways.
First:
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public void method(HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", projectUrl);
httpServletResponse.setStatus(302);
}
Second:
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method() {
return new ModelAndView("redirect:" + projectUrl);
}
You can use the RedirectView. Copied from the JavaDoc:
View that redirects to an absolute, context relative, or current request relative URL
Example:
#RequestMapping("/to-be-redirected")
public RedirectView localRedirect() {
RedirectView redirectView = new RedirectView();
redirectView.setUrl("http://www.yahoo.com");
return redirectView;
}
You can also use a ResponseEntity, e.g.
#RequestMapping("/to-be-redirected")
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI yahoo = new URI("http://www.yahoo.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(yahoo);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}
And of course, return redirect:http://www.yahoo.com as mentioned by others.
You can do this in pretty concise way using ResponseEntity like this:
#GetMapping
ResponseEntity<Void> redirect() {
return ResponseEntity.status(HttpStatus.FOUND)
.location(URI.create("http://www.yahoo.com"))
.build();
}
Looking into the actual implementation of UrlBasedViewResolver and RedirectView the redirect will always be contextRelative if your redirect target starts with /. So also sending a //yahoo.com/path/to/resource wouldn't help to get a protocol relative redirect.
So to achieve what you are trying you could do something like:
#RequestMapping(method = RequestMethod.POST)
public String processForm(HttpServletRequest request, LoginForm loginForm,
BindingResult result, ModelMap model)
{
String redirectUrl = request.getScheme() + "://www.yahoo.com";
return "redirect:" + redirectUrl;
}
Another way to do it is just to use the sendRedirect method:
#RequestMapping(
value = "/",
method = RequestMethod.GET)
public void redirectToTwitter(HttpServletResponse httpServletResponse) throws IOException {
httpServletResponse.sendRedirect("https://twitter.com");
}
For me works fine:
#RequestMapping (value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Object> redirectToExternalUrl() throws URISyntaxException {
URI uri = new URI("http://www.google.com");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(uri);
return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER);
}
For external url you have to use "http://www.yahoo.com" as the redirect url.
This is explained in the redirect: prefix of Spring reference documentation.
redirect:/myapp/some/resource
will redirect relative to the current Servlet context, while a name such as
redirect:http://myhost.com/some/arbitrary/path
will redirect to an absolute URL
Did you try RedirectView where you can provide the contextRelative parameter?
This works for me, and solved "Response to preflight request doesn't pass access control check ..." issue.
Controller
RedirectView doRedirect(HttpServletRequest request){
String orgUrl = request.getRequestURL()
String redirectUrl = orgUrl.replaceAll(".*/test/","http://xxxx.com/test/")
RedirectView redirectView = new RedirectView()
redirectView.setUrl(redirectUrl)
redirectView.setStatusCode(HttpStatus.TEMPORARY_REDIRECT)
return redirectView
}
and enable securty
#EnableWebSecurity
class SecurityConfigurer extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
}
}
In short "redirect://yahoo.com" will lend you to yahoo.com.
where as "redirect:yahoo.com" will lend you your-context/yahoo.com ie for ex- localhost:8080/yahoo.com