Can we get HttpRequest Object in Controller in Spring MVC - spring-mvc

Is it possible that I can get HttpRequest object in my Controller class in Spring MVC ?
#Controller
public class ContactController {
#Autowired
private ContactService contactService;
#RequestMapping("/login")
public String displayLoginPage(#ModelAttribute("login") Login login, BindingResult result) {
return "login";
}
}

#RequestMapping("/login")
public String displayLoginPage(HttpServletRequest request, #ModelAttribute("login") Login login, BindingResult result){
return "login";
}

Related

Sprint Rest AuthenticationPrincipal returns customUser with only null values

I am trying to get the currently logged in user (basic auth) in a spring boot REST backend:
#RequestMapping(value = "/someURL", method = RequestMethod.GET)
public #ResponseBody Map someMethod(
Authentication auth, // <==== works
#AuthenticationPrincipal(expression = "liquidoUserModel") UserModel liquidoUserModel
)
{
log.debug(auth.getPrincipal()) // <==== THIS WORKS
log.debug(liquidoUserModel) // <==== returns an intance with empty fields
}
Here is my custom UserModel
#Data // Lombok magic for all the getters and setters
#Entity
#RequiredArgsConstructor
#Table(name = "users")
public class UserModel {
#Id
Long id;
#NonNull
#Column(unique = true)
public String email;
[...]
}
And this is my UserDetailsService
public class LiquidoUserDetailsService implements UserDetailsService {
#Autowired
UserRepo userRepo;
#Override
public LiquidoAuthUser loadUserByUsername(String email) throws UsernameNotFoundException {
UserModel userModel = userRepo.findByEmail(email);
return new LiquidoAuthUser(userModel.getEmail(), userModel.getPasswordHash(), getGrantedAuthorities(userModel), userModel);
}
}
And finally the LiquidoAuthUser
public class LiquidoAuthUser extends User {
private UserModel liquidoUserModel;
public LiquidoAuthUser(String username, String password, Collection<? extends GrantedAuthority> authorities, UserModel liquidoUserModel) {
super(username, password, authorities);
this.liquidoUserModel = liquidoUserModel;
}
public UserModel getLiquidoUserModel() {
return liquidoUserModel;
}
public void setLiquidoUserModel(UserModel userModel) {
this.liquidoUserModel = userModel;
}
}
And of course I have the #EnableWebMvc annotation on my main SpringApplication class.
My problem: How can I get the currently authenticated custom UserModel in the REST handler?
The strange thing: I actually can get my custom user from the Authentication auth object. Why does the #AuthenticationPrincipal not work?
I am using spring-security-4.1.3-RELEASE
Full code is open source at https://github.com/Doogiemuc/liquido-backend-spring
I tried and debug your code but not able to find issue of
#AuthenticationPrincipal. Typically this annotation is resolved by AuthenticationPrincipalArgumentResolver class of spring security web annotation. By using #EnableWebSecurity you will automatically have this added to your Spring MVC configuration. Need to be debug more on AuthenticationPrincipalArgumentResolver that for time being I will suggest go with Authentication class and get your object.

How to port SpringMVC Application to SpringREST?

We have created SpringMVC application using Spring-Boot and Thymleaf. Now as per new requirement, I have to convert them to SPring-REST for external application consumption(AngularJS and Android App) without affecting the thymleaf pages.
Please assist.
Below is the sample code. Like this many controllers are there
#Controller
#RequestMapping(value = "/admin/register")
#SessionAttributes("roles")
public class AdminRegisterController {
#Autowired
private UserService userService;
#Autowired
private RoleRepository roleRepository;
#ModelAttribute("user")
public User constructUser() {
return new User();
}
#ModelAttribute("roles")
public List<Role> InitializeRoles() {
return roleRepository.findAll();
}
// Display Register Page
#RequestMapping
public String showRegister(Model model) {
model.addAttribute("current", "register");
return "register";
}
// Inserting new User
#RequestMapping(method = RequestMethod.POST)
public ModelAndView doRegister(#Valid #ModelAttribute("user") User user, BindingResult result) {
if (result.hasErrors()) {
return new ModelAndView("register");
}
userService.save(user);
RedirectView redirectView = new RedirectView("/admin/register?success=true");
redirectView.setExposeModelAttributes(false);
return new ModelAndView(redirectView);
}
#RequestMapping("/available")
#ResponseBody
public String available(#RequestParam String username) {
User user = userService.findOne(username);
Boolean available = userService.findOne(username) == null;
return available.toString();
}
}
You can use the javax.ws.rs api for doing that.
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
And use #RestController instead of simple #Controllers in your current code.

why customer converter do not work in spring mvc

Spring mvc controller
#RequestMapping(method = RequestMethod.GET)
public Result<String> create(Date beginDate) {
//...
}
client call this api, beginDate parameter used long type
curl 'http://localhost:8080/foos?beginDate=1459657565000'
the response is
>Error 400 Bad Request
maybe spring mvc cannot convert long to date automatically, so I wrote a customer converter
public class LongToDateConverter implements Converter<Long, Date> {
#Override
public Date convert(Long source) {
if (source == null ) {
return null;
}
return new Date(source);
}
}
#Configuration
#EnableWebMvc
public class WebMvcContext extends WebMvcConfigurerAdapter {
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new LongToDateConverter());
}
}
then I call this api again, still the same error
Error 400 Bad Request
and set breakpoint in convert method , and found it did not step into this method, So why this converter do not work?
Then I changed it to POST method
#RequestMapping(method = RequestMethod.POST)
public Result<String> create(CouponModel model) {
}
CouponModel:
private Date useBeginDate;
Still Error 400 Bad Request

Inheritance with #Controller in Spring

I would like have a #Controller parent in my app, as this:
#Controller
public class controllerParent{
public String getUser (Model model,HttpServletRequest request){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName(); //get logged in username
user = userService.findByUserName(name);
model.addAttribute("user",user);
}
}
and a child:
public class chil extends controllerParent{
#RequestMapping(value="/something.html",method = RequestMethod.GET)
public String doSomething (Model model,HttpServletRequest request){
//Code to do something
}
}
And what want to do is that in each child controller call I want show in my JSP the user . Can I do this without rewrite spring security code?

How should I add attribute after redirect to a controller

I am just a newbie about Spring.
I am now using #ExceptionHandler to handle all the exception for my web application. And after I catch the exception, it will go to and error.jsp page displaying the error message.
I have a ParentController and in that, I have:
#org.springframework.web.bind.annotation.ExceptionHandler(PortalException.class)
public ModelAndView handle(PortalException e, HttpServletRequest request) {
ModelMap map = new ModelMap();
map.addAttribute("message", e.getMessage());
return new ModelAndView("/error", map);
}
and I have a ErrorControllerextends the ParentController to add the attributes:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Model model, HttpServletRequest request) {
model.addAttribute("excetpion.message", request.getParameter("message"));
return "/error";
}
}
In the error.jsp:
<p>Excpetion is: ${exception.message}</p>
When I run my application, I can catch the exception and jump to error.jsp, but no exception message is display.
Anyone can help me to figure out how to solve it.
Please try use:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Map<String, Object> map, HttpServletRequest request) {
map.put("excetpion.message", request.getParameter("message"));
return "/error";
}
}
UPDATE
Map you get it messae from #Controller to View in this case error.jsp
I hope these helped! :)

Resources