Cannot call Play Framework static method from view - java

I have server and I should make request on button pressed also I have to call this method and when it is works I should parse json but my doesn't see controller method only main method is available
How to call
<input type="submit" onclick="#routes.Login.resp()" value="LOGIN" >
because it is not worrking Cannot resolve symbol
GET /login controllers.Login.main()
My controller:
package controllers;
import play.libs.F;
import play.libs.WS;
import play.mvc.Controller;
import play.mvc.Result;
public class Login extends Controller {
public static Result main() {
return ok(views.html.login.render());
}
public static F.Promise<Result> resp() {
String feedUrl="http://validate.jsontest.com/?json=%7B%22key%22:%22value%22%7D";
final F.Promise<Result> resultPromise = WS.url(feedUrl).get().flatMap(
new F.Function<WS.Response, F.Promise<Result>>() {
public F.Promise<Result> apply(WS.Response response) {
return WS.url(response.asJson().findPath("empty").asText()).get().map(
new F.Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok("size" + response.asJson().findPath("count").asInt());
}
}
);
}
}
);
return resultPromise;
}
}
view:
<!--
Author: W3layouts
Author URL: http://w3layouts.com
License: Creative Commons Attribution 3.0 Unported
License URL: http://creativecommons.org/licenses/by/3.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>LOGIN</title>
<meta charset="utf-8">
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/stylelogin.css")">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
<!--webfonts-->
<link href='http://fonts.googleapis.com/css?family=Open+Sans:600italic,400,300,600,700' rel='stylesheet' type='text/css'>
<!--//webfonts-->
</head>
<body>
<!-----start-main---->
<div class="main">
<div class="login-form">
<h1>Member Login</h1>
<div class="head">
<img src="#routes.Assets.at("images/user.png")" alt=""/>
</div>
<form>
<input type="text" class="text" value="USERNAME" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'USERNAME';}" >
<input type="password" value="Password" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Password';}">
<div class="submit">
<input type="submit" onclick="#routes.Login.main()" value="LOGIN" >
</div>
</form>
</div>
<!--//End-login-form-->
<!-----start-copyright---->
<!-----//end-copyright---->
</div>
<!-----//end-main---->
</body>
</html>
I am not sure if I also parse json properly,how to make proper GET,POST requests and parse it

As far as I know with the onclick attribute you always call a function in your JavaScript. If you want to specify an URL you need to put it into your form tag with an action attribute like <form action="#routes.Login.main()">.
The default for the HTML form tag is to send a GET. If you want to send a POST you have to specify it via an additional method="post" like <form action="#routes.Login.main()" method="post">. But then you have to change your routing too: POST /login controllers.Login.main(). If you want to post login data I'd strongly recommend to use POST because with GET your data including the password turns up in the query string of your URL.
Additionally your #routes.Login.main() method just returns the login view return ok(views.html.login.render());. Instead it should evaluate the form data you are sending.

Related

SpringBoot Thymeleaf: No mapping for GET /css/style.css

I'm trying to add .css file to my index.html using Thymeleaf. But browser throws some strange errors:
GET http://localhost:8080/css/style.css net::ERR_ABORTED 404
And on server i got:
o.s.web.servlet.PageNotFound : No mapping for GET /css/style.css
Why it's happens? Also, it happens with all static components like .js and .css files. I have not any security. Please, help!
Sources:
WebConfig.java
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*").allowedOrigins("*");
}
}
AdminPanel.java
#ConditionalOnProperty("app.is_debugging")
#Controller
public class AdminPanel {
#RequestMapping(value = { "/", "/index" }, method = RequestMethod.GET)
public String getIndex(Model model) {
return "index";
}
}
index.html
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Custom messanger</title>
<link rel="stylesheet" type="text/css" th:href="#{/css/style.css}"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.0/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.1.1/list.min.js"></script>
<!-- libs for stomp and sockjs-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.4.0/sockjs.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
<!-- end libs for stomp and sockjs-->
<script type="text/javascript" th:src="#{/js/chat.js}"></script>
</head>
<body>
<div class="container clearfix">
<input type="text" id="name" placeholder="name">
<button onclick="createRoom()">Create room</button>
<input type="text" id="roomId" placeholder="roomId">
<button onclick="connectToTheRoom()">Connect</button>
<button onclick="connectToSocket()">Connect to socket</button>
<input type="text" id="message" placeholder="message">
<button onclick="sendMsg()">Send</button>
</div>
<div id="messagesList">
<a class="messagesConsole">Test msg1</a>
<a class="messagesConsole">Test msg2</a>
</div>
</body>
</html>
My file structure

Unsupported Media Type error in browser console when sending json using angularjs to spring controller

Here is my controller function
#RequestMapping(value = "/logInChecker", method = RequestMethod.POST, consumes = {"application/json"})
public #ResponseBody String logInCheckerFn(#RequestBody UserLogData userLogData){
Integer userAuthFlag = goAnalyserModel.checkUserAuth(userLogData);
return userAuthFlag.toString();
}
My Bean class
public class UserLogData {
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
My html file with angularjs function
<!DOCTYPE html>
<html lang="en" ng-app="nameAppIndexPage">
<head>
<meta charset="utf-8">
<title>Go Analyser - Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<!-- Le styles -->
<link href="assets/css/bootstrap.css" rel="stylesheet">
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
</style>
<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
</head>
<body ng-controller="nameController">
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="#">Go Analyser</a>
</div>
</div>
</div>
<div class="container">
<!-- Example row of columns -->
<div class="row">
<div class=" margin_alignment"></div>
<div class="span4"></div>
<div class="span4">
<form class="form-signin">
<label for="exampleInputEmail1">Email address</label>
<input type="text" class="input-block-level" placeholder="Email address" ng-model="userName">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="input-block-level" placeholder="Password" ng-model="password">
<!-- <center><button class="btn btn-large" type="submit">Login</button></center>-->
<button type="submit" ng-click='checkLogin()'>login</button>
</form>
</div>
<div class="span4"></div>
</div>
<div class="hr_space"></div>
<footer>
</footer>
</div>
<script src="assets/js/jquery.js"></script>
<script src="assets/js/angular.js"></script>
<script>
var myApp = angular.module('nameAppIndexPage',[]);
myApp.controller('nameController',function($http,$scope){
$scope.checkLogin = function(){
alert("inside checklogin()");
var userName = $scope.userName;
var password = $scope.password;
var dataToSend = {
"userName" : userName,
"password" : password
};
console.log(dataToSend);
alert("after data to send");
$http.post('logInChecker',dataToSend).success(function(data){
if(data == 1){
alert("inside loginSuccess");
}else{
alert("username and password mismatch");
//write function to show incorrect password
}
}).error(function(data){
alert("error in post" + JSON.stringify({data: data}));
});
}
});
</script>
</body>
</html>
I keep getting unsupported media error in browser console. The angularjs function is not getting the request through to the spring controller. But every thing seems to be fine.
This message happens either when the request cannot be converted to a java object, or when a java object cannot be converted to response.
As you've explained, you have the former case. Few things that you should check:
check that you have the <mvc:annotation-driven /> in your servlet configuration
check that you have jackson dependencies on your classpath, for spring 4.x you should have the jackson 2.x version, for spring 3.x you should use jackson 1.9
to ensure that your response is also properly converted you should, besides having the proper dependencies, ensure that
Either an Accept header is sent with your request with the value application/json or that the RequestMapping annotation of your handler method has the attribute produces = {"application/json"}
Add #JsonProperty("**") (**Name of the property) to your bean class. Check in the browser's developer tool type of JSON post messages.

Set Ajax response on jsp not working

Last few hours i am trying to solve this but i can not.I am sending ajax request using jquery and based on response i set data on jsp.actully i am checking login detail so if login fail it set error message on label problem is that error message is set for few second and removed i mean to say error message is set for few second i want that if login fails the message is set on label still user enter valid details
thanks in advance
Here is my code
LoginDemo.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link href="css/firstpage.css" rel="stylesheet" type="text/css" /><!-- <style> -->
<script src="js/jquery.min.js"></script>
<title>Insert title here</title>
<script>
$(document).ready(function(){
$("#submit").click(function(){
$.ajax({
type: "POST",
url: "AddInspServlet",
cache:false,
data: { userid: $('#username').val(), password: $('#password').val(),btn:$('#submit').val() },
success:function(data,textstaus){
alert("success:"+data);
if(data == "no"){
alert( document.getElementById("error").innerHTML);
document.getElementById("error").innerHTML= "UserName OR Password is incorrect";
alert( document.getElementById("error").innerHTML);
}else{
location.href = 'Home.jsp';
}
},
error:function(data){
alert("error"+data);
},
});
});
});
</script>
</head>
<body>
<form id="login" name="Loginform" method="post">
<h1><b>Log In</b></h1>
<fieldset id="inputs">
<input id="username" type="text" placeholder="Username" autofocus required>
<input id="password" type="password" placeholder="Password" required>
</fieldset>
<fieldset id="actions">
<input type="submit" id="submit" value="login">
Forgot your password?
</fieldset>
<label id="error" style="color: red;font: bolder; font-size: 18px;">
</label>
</form>
</body>
AddInspServlet
Here i m adding code which server executed and retrieve response
if(btn.equals("login"))
{
System.out.println("***** login condition checking ******");
String password =request.getParameter("password");
UserVO v =op.loginCheck(username, password);
if(password.equals(v.getPassword()))
{
System.out.println("inside true condition");
HttpSession session = request.getSession();
session.setAttribute("userid",v.getUser_id());
session.setAttribute("username",v.getUsername());
session.setAttribute("user", v.getFirst_name()+" "+v.getLast_name());
session.setAttribute("roleid", v.getRole_id());
// response.sendRedirect("Home.jsp");
System.out.println("submitting data success fully");
out.print("yes");
}
else
{
System.out.println("false condition");
out.print("no");
}
}
Get rid of the form tags.
By adding a type="submit" input element without using the action attribute in the form tag, the page will be reloaded.
Or you could keep the form tags and change the type of the submit button to type="button". The form will then not be executed and the page will not reload.
It would be better if you be more specific about the problem. I assume your problem is Label is getting displayed for few seconds and then get disappeared. Is that is true? then try to return "false" inside you data == "no" logic.
Thanks.

Retain the value of textbox when an error occurs in spring

I am developing a webapp. In that app i have a page which have three search options based on id. If the ID is wrong i want to retain the id in search textbox and i want to show an error message. I tried that with
ModelAndView.addObject("id", value);
And this is working fine , Now i want to know if there is a better way to do this because assume i have a big form and i want to retain the value of every field than it will be difficult using the above approch. Please help!
And i am using search by ID and Name both thats why i have try and catch blocks
this is my jsp file
html>
<head>
<link rel="stylesheet" type="text/css" href="./css/style.css" />
<link rel="stylesheet" type="text/css" href="./bootstrap/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="./bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="./bootstrap/css/bootstrap-responsive.css" />
<link rel="stylesheet" type="text/css" href="./bootstrap/css/bootstrap-responsive.min.css" />
<script>
function redirectToSearchResult(textBoxId){
window.location.href= document.getElementById(textBoxId).name+'.htm?'+'id='+document.getElementById(textBoxId).value;
}
</script>
</head>
<body>
<div class="page-header"></div>
<div id="searchByBuyer">
<label id="E_B_I"><h2>Buyer Search<h2></label><br>
<input type="text" id="S_B_B" class="text-box" name="searchByBuyer" value=${buyerId} ></input>
<input type="button" id="BuyerSearch" class="btn-custom" value="search" onclick="redirectToSearchResult('S_B_B')"/>
</div>
<div id="searchByCategory">
<label id="E_C_I"><h2>Category Search<h2></label><br>
<input type="text" id="S_B_C" class="text-box" name="searchByCategory" value=${categoryId} ></input>
<input type="button" id="CategorySearch" class="btn-custom" value="search" onclick="redirectToSearchResult('S_B_C')"/>
</div>
<div id="searchByArticle">
<label id="E_A_I"><h2>Article Search<h2></label><br>
<input type="text" id="S_B_I" class="text-box" name="searchByArticle" value=${articleId} ></input>
<input type="button" id="ArticleSearch" class="btn-custom" value="search" onclick="redirectToSearchResult('S_B_I')"/><br>
</div>
<br>
<label style="color:red; padding-left:45em; padding-top:15em"><h4>${error}</h4></label>
</body>
</html>
And this my controller
`
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class BuyerController {
#Autowired
private BuyerRepo buyerRepo;
#RequestMapping(value = "/searchByBuyer.htm", method = RequestMethod.GET)
public ModelAndView searchFields(#RequestParam(value = "id") String buyerId) throws InvalidIdException {
Buyer buyer = null;
ModelAndView buyerSearch = new ModelAndView("buyerSearch");
ModelAndView errorView = ErrorView.getErrorView("buyerId", buyerId, "Enter a valid Buyer id!");
try {
buyer = buyerRepo.getBuyer(Long.parseLong(buyerId));
} catch (NumberFormatException e) {
buyer = buyerRepo.getBuyer(buyerId);
if (buyer == null) return errorView;
} catch (Exception e) {
buyerSearch = errorView;
}
buyerSearch.addObject("buyer", buyer);
return buyerSearch;
}
}
`
This is the error and view class to create error view with parameters
`
import org.springframework.web.servlet.ModelAndView;
public class ErrorView {
public static ModelAndView getErrorView(String key, String value, String message) {
ModelAndView errorView = new ModelAndView("index");
errorView.addObject("error", message);
errorView.addObject(key, value);
return errorView;
}
}
`
Spring has JSR 303-Bean-Validation support for web forms.
This build in way is much easyer to use than some own implementation.
You need:
a command object that gets all the values from the form. Each fields can have JSR 303-Bean-Validation annotations to indicate the constaints you want to enforce
you need a web controller method with (at least) two parameters: #Valid command object, BindingResult (The BindingResult must be THE parameter after the command object)
in you web controller method you need to check the BindingResult, and if it has failure you need to render the form again
in your form you need to use form:errors to show the errors (form:errors can also show the errors for an specific field)
you need some spring configuration: <mvc:annotation-driven /> (there is more possible but this should be enough for the begin)
you need a JSR 303-Bean-Validation libary, for example: Hibernate Validator (this is not the Hibernate ORM)
But an example explain it the best: http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/

Set a request attribute depending on the link clicked

I would like to determine which link is being click, and set a request attribute accordingly; to be processed in the controller. The controller is generic. It will dispatch to another page according to the attribute set in the JSP. How can I achieve this?
EDIT:
I have followed the BalusC's advice where
Register
Login
RandomController :
#WebServlet(name = "RandomController", urlPatterns = {"/RandomController/*"})
public class RandomController extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int theRandom = 0;
Random myRandom = new Random();
RequestDispatcher dispatcher = null;
String pathInfo = request.getPathInfo();
String contextPath = request.getContextPath();
String dispatchesPath = contextPath + pathInfo;
System.out.println(pathInfo);
System.out.println(contextPath);
System.out.println(dispatchesPath);
theRandom = myRandom.nextInt(MAX_RANDOM);
request.setAttribute("random", theRandom);
if(pathInfo.equals("/Login")) {
dispatcher = request.getRequestDispatcher("Login.jsp");
dispatcher.forward(request, response);
}
else {
dispatcher = request.getRequestDispatcher("Register.jsp");
dispatcher.forward(request, response);
}
}
}
I have tried this approach but the Exception about maximum depth for nested request dispatchers : 20 is throw.
The generic controller is RandomController which servers two produces random number and set as attribute in request object and sent it to login or register page.
Login.jsp :
<%--
Document : Register
Created on : May 28, 2011, 5:49:35 PM
Author : nicholas_tse
--%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Online Store Register Page</title>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
</head>
<body>
<jsp:useBean id="randomBean" class="Helper.RandomInt"
scope="request">
</jsp:useBean>
<h1>Online Store</h1>
<p></p>
<div align="right">
<h3>
<c:if test="${not empty sessionScope.username}">
! Welcome ${sessionScope["username"]} !
<form action="LogoutController" method="POST">
<input type="submit" name="submit" value="Logout"/>
</form>
</c:if>
</h3>
</div>
<ul id="nav_list">
<li>Home</li>
<li>Product</li>
<li>Add Stock</li>
<li>Shopping Cart</li>
<li>Order Status</li>
<li>Register</li>
<li>Login</li>
</ul>
<br></br>
<p></p>
<c:if test="${!not empty sessionScope.username}">
<div id="registerForm" align="center"
style="border:1px solid black; width:760px" >
<form name="RegisterForm" action="RegisterController"
method="POST">
<p>
Username : <input type="text" id="username" name="username">
<c:if test="${message.msg} != null" >
${message.msg}
</c:if>
</p>
<p>
Password : <input type="password" id="password" name="password"
</p>
<p>
Name : <input type="text" id="name" name="name">
<c:if test="${message.msg} != null" >
${message.msg}
</c:if>
</p>
<p>
Address : <input type="text" id="address" name="address">
<c:if test="${message.msg} != null" >
${message.msg}
</c:if>
</p>
<p>
State :
<select>
<option>Selangor</option>
<option>Kuala Lumpur</option>
<option>Cyberjaya</option>
<option>Putrajaya</option>
</select>
</p>
<p></p>
<input type="submit" name="submit" value="Register">
<input type="reset" name="clear" value="Clear">
<p></p>
</form>
</div>
</c:if>
</body>
</html>
Without further info the only suggestion I can think of is to add a querystring to your URLs. Like this:
Page 1
This way you can look at the actiuon parameter in the request to determine what to do in your controller.
You can add a request parameter. This can be done in 2 ways depending on whether your form has a method of POST or GET.
You have implemented the submit buttons in the forms with a name attribute of submit and different value attributes. This should mean that the requests will include a submit parameter in the query string or the POST form data. On the server side, you can use this to figure out which of the submit buttons was clicked.

Categories