RequestMethod.GET not getting envoked - spring-boot

My code looks as follows:
#Controller
public class ImporterErrorsController {
#RequestMapping(value = "importerErrors", method = RequestMethod.GET)
public String importerErrors(WebRequest webRequest, Model model) {
return "importerErrors";
}
}
And
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a th:href="#{/importerErrors}">Errors</a></li>
</ul>
</div>
For some reason when I click the errors button in the navbar, the method importErrors does not get invoked. I have successfully run some POST methods inside a form but for some reason i cannot get the GET method to get invoked. Additionally, I managed to do something similar in a different project.
Please let me know if I am doing something wrong.

Related

Laravel calling controller function from blade file not working

I have a Laravel project where I'm trying to call a controller function from blade file called nav.blade.php, but I'm getting following error:
syntax error, unexpected fully qualified name
"\App\Http\Controllers\ProductC...", expecting ":".
nav.blade.php
{{ use \App\Http\Controllers\ProductController; }}
<div class="container">
<ul class="navbar-nav mr-auto">
{{ $is_admin = ProductController::isAdmin(); }}
#if($is_admin == "admin")
<li class="nav-item">
<a class="nav-link" href="/posts">Admin</a>
</li>
#endif
</ul>
</div>
ProductsController.php
public static function isAdmin()
{
$user_id = Auth::id();
$user = User::findOrFail($user_id);
$is_admin = $user->role;
if($is_admin==="admin"){
return "admin";
}elseif($is_admin==="moderator"){
return "moderator";
}else{
return "user";
}
}
You access the static controller function from the blade template.
<?php
$isAdmin= App\Http\Controllers\ProductController::isAdmin();
?>
{{ }} are used to echo anything you want. If you want to import a class, one solution is to do like the following:
<?php
use \App\Http\Controllers\ProductController;
$is_admin = ProductController::isAdmin();
?>
<div class="container">
<ul class="navbar-nav mr-auto">
#if($is_admin == "admin")
<li class="nav-item">
<a class="nav-link" href="/posts">Admin</a>
</li>
#endif
</ul>
</div>
But this isn't a best practice I recommend you to move isAdmin() method from ProductController and set it as global function of your system so you can directly access it from your view without importing a controller.
Never EVER use a controller in a Blade. That is not good in any way and would require me a lot of explanation that is already in some blogs...
A controller is ONLY used for accessing something through a URL, do something and done, it is not a Service class where you do business logic anywhere you want.
So, move that method to a Service class (do not confuse with Service Provider) and use it in the blade. It would still be better to pass that variable to the view and not using any class just for that...

FormatException and ArgumentException errors

I get these errors in Visual Studio in an ASP.NET Core 2.1 application while attempting to change identity from string to long. Has anyone else run into these errors?
An unhandled exception occurred while processing the request.
FormatException: Input string was not in a correct format.
System.Number.StringToNumber(ReadOnlySpan str, NumberStyles
options, ref NumberBuffer number, NumberFormatInfo info, bool
parseDecimal) ArgumentException: 81d1aa6c-b70a-4d64-a62a-e177d79b944e
is not a valid value for Int64. Parameter name: value
System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext
context, CultureInfo culture, object value)
For changing Identity primary key from string to long, follow steps below:
Add ApplicationUser.cs
public class ApplicationUser:IdentityUser<long>
{
}
Modify ApplicationDbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<long>, long>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Modify Startup.cs
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
Modify _LoginPartial.cshtml from IdentityUser to ApplicationUser
#using Microsoft.AspNetCore.Identity
#inject SignInManager<ApplicationUser> SignInManager
#inject UserManager<ApplicationUser> UserManager
#if (SignInManager.IsSignedIn(User))
{
<form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="#Url.Action("Index", "Home", new { area = "" })" method="post" id="logoutForm" class="navbar-right">
<ul class="nav navbar-nav navbar-right">
<li>
<a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello #UserManager.GetUserName(User)!</a>
</li>
<li>
<button type="submit" class="btn btn-link navbar-btn navbar-link">Logout</button>
</li>
</ul>
</form>
}
else
{
<ul class="nav navbar-nav navbar-right">
<li><a asp-area="Identity" asp-page="/Account/Register">Register</a></li>
<li><a asp-area="Identity" asp-page="/Account/Login">Login</a></li>
</ul>
}

How to set the login/logout link visible/invisible with Thymeleaf?

I am a beginner in Spring Framework. I try to make login and logout Thymeleaf pages. Below codes are the Spring Boot login/logout files with Thymeleaf.
First, Login Controllers codes
#Autowired
private HttpSession userSession;
#Autowired
private UserService userService;
#RequestMapping("/users/login")
public String login(LoginForm loginForm) {
return "users/login";
}
#RequestMapping(value="/users/login", method = RequestMethod.POST)
public String loginPage(#Valid LoginForm loginForm, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
userSession.setAttribute("blogLogin", false);
System.out.println("Wrong Input!!");
return "users/login";
}
if(!userService.authenticate(loginForm.getUsername(), loginForm.getPassword())) {
userSession.setAttribute("blogLogin", false);
System.out.println("login failed!!");
return "users/login";
}
userSession.setAttribute("blogLogin", true);
System.out.println("Login succesfully.");
return "redirect:/";
}
And the layout.html codes using thymeleaf.
<header th:fragment="site-header" th:remove="tag">
<header>
<a href="index.html" th:href="#{/}">
<img src="../public/img/site-logo.png" th:src="#{/img/site-logo.png}" />
</a>
Home
Log in
Log out
Register
Users
Posts
Write Post
<div id="logged-in-info"><span>Hello, <b>(user)</b></span>
<form method="post" th:action="#{/users/logout}">
<input type="submit" value="Log out"/>
</form>
</div>
</header>
</header>
The problem is I have no idea how to make login/logout link toggling codes using th:if statement of thymeleaf. As you know login link and logout link can not be displayed simultaneously.
you can check whether user is authenticated or anonymous like below and can make decisions.
<div sec:authorize="#{isAuthenticated()}">
<a th:href="#{/logout}">Log out</a>
</div>
<div sec:authorize="#{isAnonymous()}">
<a th:href="#{/login}">Log in</a>
</div>

Strange behavior observed with Spring 3.1 Controller

I'm using Spring 3.1 and tiles to develop a MVC app.
I have a JSP page (header.jsp) and 2 controllers (HomeController and SignupController).
The header.jsp is like this:
<s:url var="login_url" value="${loginUrl}" />
<s:url var="signup_url" value="${signUpFormUrl}" />
<a class="btn btn-primary" href="${login_url}">Login</a>
<a class="btn btn-default" href="${signup_url}">Signup</a>
The HomeController.java is like this (the /login/form URL is configured to be used by spring security as login page):
#Controller
public class HomeController {
#RequestMapping({"/", "/home"})
public String showHomePage(final Map<String, Object> model) {
return "home";
}
#ModelAttribute("loginUrl")
public String getLoginUrl() {
return "/login/form";
}
......
}
The SignupController.java is like this:
#Controller
public class SignupController {
.....
#RequestMapping(value = "/signup/form")
public String signup(#ModelAttribute SignupForm signupForm) {
return "signup/form";
}
#ModelAttribute("signUpFormUrl")
public String getSignUpFormUrl() {
return "/signup/form";
}
.....
}
What's strange is that like it is presented above I got this result when the page is rendered:
<a class="btn btn-primary" href="/appContext/login/form">Login</a>
<a class="btn btn-default" href="">Signup</a>
So the ended up with empty href value.
BUT when I moved around the signup controller code regarding the signup (the RequestMapping and the ModelAttribute method) to the home controller, it worked as expected:
<a class="btn btn-primary" href="/appContext/login/form">Login</a>
<a class="btn btn-default" href="/appContext/signup/form">Signup</a>
Is it possible to use RequestMapping from different Controller inside a same view?
Can someone has a view on what is going on here?
Thanks in advance. I can supply anything other (config?) needed to understand further the problem.

Is't possible to get access to <ul> and <li> during submiting form

I have view with controller. I would like to know if it is possible to get access to ul and li? I don't want to do ajax call and pass these elements as parameters. Li elements are added on client side dynamically. this.Request.Form show me only 'name' variable without 'list'. Any advices?
<form action="#Url.Action("Filter")" method="POST">
<ul data-role="listview" data-inset="true" data-filter="false" name="list">
#foreach (var item in #Model.Items)
{
<li value="#item">#item</li>
}
</ul>
<input type="text" name="name"/>
<inpu type="submit" value="Filter"/>
</form>
and controller:
[HttpPost]
public ActionResult Filter(string name, List<string> list)
{
// working with list
return RedirectToAction("Index");
}
thanks
No,
It is not possible to access <ul> and <li> on post back.
BTW, the following code is generates <li> on server not on client
#foreach (var item in #Model.Items)
{
<li value="#item">#item</li>
}
If you wish to access Items (#item) on server, there are other ways to get those that do not require access to <ul> or <li>
For instance, you can emit a hidden (#Html.HiddenFor) element in each <li> in your loop.
You can try the following.
I'm not sure what your view model looks like, but it seems like a list of string values? So then it will look like this in your view model:
public class YourViewModel
{
public List<string> Items { get; set; }
}
In your view try the following:
<ul>
#for (int i = 0; i < Model.Items.Count(); i++)
{
<li>
#Html.DisplayFor(x => x.Items[i])
#Html.HiddenFor(x => x.Items[i])
</li>
}
</ul>
When you post then these items should still be in the list.
It might not be a perfect solution but it can guide you on the right track.
I hope this helps.

Resources