I followed this code sample https://kotlinlang.org/docs/tutorials/spring-boot-restful.html to get a basic spring boot application working.
Now I want to add frontend components through thymleaf. Passing variables into the Model dont are always null in the outputted html
controller
#Controller
class IndexController {
#GetMapping("/")
fun index(#RequestParam(value = "name", defaultValue = "brian") name: String, model: Model): String {
model.addAttribute("name", name)
model.addAttribute("title", "some title")
return "index"
}
}
resources/templates/index.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${title}"></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div class="page-content">
<h1 th:text="|Hello ${name}!|"></h1>
<h2 th:text="|Welcome to ${title} application|"></h2>
</div>
</body>
</html>
spring seems to a lot of things under the hood so maybe i missing something obvious.
and the build gradle
plugins {
id("org.springframework.boot") version "2.1.6.RELEASE"
id("io.spring.dependency-management") version "1.0.7.RELEASE"
kotlin("jvm") version "1.2.71"
kotlin("plugin.spring") version "1.2.71"
}
group = "com.ghost"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenCentral()
}
//extra["springCloudVersion"] = "Greenwich.SR1"
dependencies {
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// implementation("org.springframework.cloud:spring-cloud-gcp-starter")
// implementation("org.springframework.cloud:spring-cloud-gcp-starter-storage")
// implementation("org.springframework.cloud:spring-cloud-starter-sleuth")
implementation("org.springframework.session:spring-session-core")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
//dependencyManagement {
// imports {
// mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
// }
//}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
Related
I m studying spring security.
I want to display original html file(loginForm) in spring security when I click localhost/8080:loginForm.
but it shows default page of spring security.
it says please sign in(which i didnt make)
How can I modify it?
build gradle
plugins {
id 'org.springframework.boot' version '2.4.1'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
// springsecurityを依存関係に追加
implementation 'org.springframework.boot:spring-boot-starter-security'
// thymeleaf拡張ライブラリを依存関係に追加
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
SecurityConfig.java
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/loginForm").permitAll()
.anyRequest().authenticated(); //
http.formLogin()
.loginProcessingUrl("/login")
.loginPage("/loginForm")
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/home", true)
.failureUrl("/loginForm?error");
LoginController.java
#Controller
public class LoginController {
#GetMapping("/loginForm")
public String getLogin() {
return "loginForm";
}
}
loginForm.html(what I want to display)
<body>
<div th:if="${param.error}">
<p>ユーザ名またはパスワードが違います。</p>
</div>
<form th:action="#{/login}" method="post">
<div>
<label>メールアドレス: </label>
<input type="email" name="email">
</div>
<div>
<label>パスワード: </label>
<input type="password" name="password">
</div>
<div>
<input type="submit" value="ログイン">
</div>
</form>
</body>
My build.gradle file:
task wrapper(type: Wrapper) {
gradleVersion = '2.4'
}
buildscript {
repositories {
mavenCentral()
maven { url "http://repo.spring.io/release" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
repositories {
mavenCentral()
maven { url "http://repo.spring.io/release" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-jdbc")
compile("org.springframework.boot:spring-boot-starter-security")
testCompile("org.springframework.boot:spring-boot-starter-test")
runtime("org.apache.tomcat.embed:tomcat-embed-jasper")
runtime("postgresql:postgresql:9.1-901.jdbc4")
runtime("net.sourceforge.jtds:jtds:1.3.1")
runtime("javax.servlet:jstl:1.2")
runtime("org.springframework.security:spring-security-taglibs")
}
My controller file:
package com.mycompany.springtutorialapp;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
#Controller
#RestController
public class RootController {
#RequestMapping(value = { "/"}, method = RequestMethod.GET)
public ModelAndView defaultPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Welcome to Spring Tutorial Web Application");
model.addObject("message", "Home page of Spring Tutorial WebApp");
model.setViewName("index");
return model;
}
#RequestMapping(value = "/admin**", method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Login Form - Database Authentication");
model.addObject("message", "This page is for ROLE_ADMIN only!");
model.setViewName("admin");
return model;
}
#RequestMapping(value = "/login", method = { RequestMethod.GET, RequestMethod.POST })
public ModelAndView login(#RequestParam(value = "error", required = false) String error,
#RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("login");
return model;
}
//for 403 access denied page
#RequestMapping(value = "/403", method = RequestMethod.GET)
public ModelAndView accesssDenied() {
ModelAndView model = new ModelAndView();
//check if user is login
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof AnonymousAuthenticationToken)) {
UserDetails userDetail = (UserDetails) auth.getPrincipal();
model.addObject("username", userDetail.getUsername());
}
model.setViewName("403");
return model;
}
#RequestMapping("/greeting")
public ModelAndView greeting(#RequestParam(value="name", required=false, defaultValue="User") String name) {
ModelAndView mav = new ModelAndView();
mav.setViewName("greeting");
String str = "Hello " + name + "!";
mav.addObject("message", str);
return mav;
}
}
My security config:
package com.mycompany.springtutorialapp;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private DataSource authDBDataSource;
#Autowired
public void setDataSource(DataSource dataSource){
authDBDataSource = dataSource;
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(authDBDataSource)
.usersByUsernameQuery("select name, password, enabled from public.jdbcauth where username=?")
.authoritiesByUsernameQuery("select name, role from public.jdbcauth where username=?");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.and()
.formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("name").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf();
}
}
Login.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%#page session="true"%>
<html>
<head>
<title>Login Page</title>
<style>
.error {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
.msg {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
#login-box {
width: 300px;
padding: 20px;
margin: 100px auto;
background: #fff;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border: 1px solid #000;
}
</style>
</head>
<body onload='document.loginForm.username.focus();'>
<h1>Spring Security Login Form (Database Authentication)</h1>
<div id="login-box">
<h2>Login with Username and Password</h2>
<c:if test="${not empty error}">
<div class="error">${error}</div>
</c:if>
<c:if test="${not empty msg}">
<div class="msg">${msg}</div>
</c:if>
<form name='loginForm'
action="<c:url value='/j_spring_security_check' />" method='post'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username'></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="submit" /></td>
</tr>
</table>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</div>
</body>
</html>
My database is setup correctly. The POSTGRES JDBC drivers are also in path (I was able to create another DAO, connect to the database and query the authtable described above).
When I type in localhost:8080/login, the login screen is displayed correctly. However, after filling in credentials, if I hit the submit button, I get the following error:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Jun 22 12:02:03 IST 2015
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'POST' not supported
On the server console, I get the following log:
2015-06-22 12:04:01.846 WARN 9178 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : Request method 'POST' not supported
What am I doing wrong?
There are 2 things flawed in your setup.
You should post to /login instead of /j_spring_security_check as that is the new URL when using java config (and in Spring 4 for XML config also).
You have set the usernameParameter to name and your form still has username.
Fix those flaws in your login page.
Hey I got this problem when running my application in jetty.
I create some application web base on java with spring framework and maven.
When I want to try to login into my site, i got an error.
This error log from jetty:
javax.el.PropertyNotFoundException: /screens/login.xhtml #30,138 value="#{securityBean.userId}": Target Unreachable, identifier 'securityBean' resolved to null
at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:97)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:91)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1023)
at javax.faces.component.UIInput.validate(UIInput.java:953)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1204)
at javax.faces.component.UIInput.processValidators(UIInput.java:693)
at javax.faces.component.UIForm.processValidators(UIForm.java:240)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1081)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1081)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1159)
This my login.xhtml:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<f:view contentType="text/html">
<h:head>
<title>igate web admin</title>
<meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
<link type="text/css" rel="stylesheet" href="#{request.contextPath}/themes/bootstrap/bootstrap.css" />
<link type="text/css" rel="stylesheet" href="#{request.contextPath}/themes/bootstrap/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="#{request.contextPath}/themes/bootstrap/bootstrap-theme.css" />
<link type="text/css" rel="stylesheet" href="#{request.contextPath}/themes/bootstrap/bootstrap-theme.min.css" />
<ui:insert name="head"></ui:insert>
</h:head>
<h:body>
<div class="container">
<h:form class="form-signin" role="form">
<div class="logo"></div>
<h2 class="form-signin-header" style="text-align: center; color: white"> LOGIN I-GATE</h2>
<h:inputText class="form-control" required="true" requiredMessage="Username harus diisi" id="uname" value="#{securityBean.userId}"/>
<br></br>
<h:inputSecret class="form-control" required="true" requiredMessage="Password harus diisi" value="#{securityBean.password}"/>
<button class="btn btn-lg btn-primary btn-block" type="submit" action="#{securityBean.login}" ajax="false">Sign in</button>
<h4 style="text-align: center; color: white;">Please login with your Username and Password</h4>
</h:form>
</div>
</h:body>
And this my securityPage.java:
#ManagedBean( name="securityBean" )
#SessionScoped
public class SecurityPage {
private String userId;
private String password;
private UserDao userDao;
private Logger log = Logger.getLogger( SecurityPage.class );
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
/**
* use to clear properties in this class
*
*/
private void clearPage() {
this.userId = null;
this.password = null;
}
/**
* Executed to validate username and password
*
* #return String
*/
public String login() {
userDao = ( UserDao ) ServiceLocator.getService( "userDao" );
try {
String pass = Secure.digest( password );
MUser user = userDao.login( userId, pass );
if( user != null ) {
SessionUtil.setUserSession( user );
SessionUtil.setObject( Constant.LOGIN_ROLENAME, user.getRoleName() );
}
else {
FacesContext.getCurrentInstance().addMessage(
"msgs",
new FacesMessage( FacesMessage.SEVERITY_WARN,
"User ID atau Password anda tidak valid.",
"User ID atau Password anda tidak valid." ) );
clearPage();
return "login_failed";
}
}
catch( Exception e ) {
FacesContext.getCurrentInstance().addMessage(
"msgs",
new FacesMessage( FacesMessage.SEVERITY_WARN,
"User ID atau Password anda tidak valid.",
"User ID atau Password anda tidak valid." ) );
clearPage();
return "login_failed";
}
clearPage();
return "login_success";
}
/**
* Logout Action
*
* Executed to invalidate session and logout user
*
* #return String
*/
public String logout() {
log.info( "user logout from application" );
try {
SessionUtil.invalidate();
}
catch( Exception e ) {
log.error( e );
}
return "/screens/login.jsf?faces-redirect=true";
}
}
I stuck on this problem. I've tried to follow another suggestion from stackoverflow. but no one can fixed this. Please help :)
Thanks.
I'm trying to configure a Kendo grid and I'm having issues when trying to add properties such as sorting, grouping, etc. The grid works until I add the property, then it doesn't display any of the data. I have looked at the documentation on Kendo's site and it looks as if I have everything the same as theirs but obviously I'm nissing something.
Here is the View:
#model ExampleKendoUI.Models.HeaderVm
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div>#Model.Name</div>
#section scripts {
<script>
// Output the data as JSON
var podata = #Html.Raw(Json.Encode(ViewBag.LineItems));
</script>
<div id="poGrid" class="k-content">
<script>
$(document).ready(function () {
$("#poGrid").kendoGrid({
dataSource: {
data: podata
},
// sortable:true, *** Uncommenting this will break the grid ***
columns: [
{
field: "Description",
title: "Desc"
},
{
field: "Quantity",
title: "Quantity"
}
]
});
});
</script>
</div>
}
Here is the controller:
namespace ExampleKendoUI.Controllers
{
public class SampleController : Controller
{
//
// GET: /Sample/
public ActionResult Index(int id)
{
var header = new HeaderVm()
{
Id = id,
Name = "Req ID"
};
var results = new List<PoLineVm>()
{
new PoLineVm()
{
Id = 1,
Description = "Some Product",
Quantity = 1.5
},
new PoLineVm()
{
Id = 2,
Description = "Another Product",
Quantity = 4.0
},
new PoLineVm()
{
Id = 3,
Description = "Last Product",
Quantity = 20
},
};
ViewBag.LineItems = results;
return View(header);
}}}
Here is the _Layout:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
<link href="~/Content/kendo/2012.3.1114/kendo.default.min.css" rel="stylesheet" />
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
#RenderBody()
#Scripts.Render("~/bundles/jquery")
<script src="/scripts/kendo/2012.3.1114/kendo.core.min.js"></script>
<script src="~/Scripts/kendo/2012.3.1114/kendo.data.min.js"></script>
<script src="~/Scripts/kendo/2012.3.1114/kendo.grid.min.js"></script>
#RenderSection("scripts", required: false)
</body>
</html>
You haven't included the required JavaScript files and the JavaScript error means that kendoSortable is missing. Check the documentation for the required JavaScript files: http://docs.kendoui.com/getting-started/javascript-dependencies
I'm a newbie in SignalR. I'm trying to do this Progress Bar example.
I can't download and install the packages via NuGet, cause there is a proxy in my work that denies the access. So I include de DLLs and the scripts in project by myself.
My view code is below:
<h2>#ViewBag.Message</h2>
<input type="button" id="bookButton" value="Book flight" />
<br />
<b>Status:</b> <span id="msg"></span>
<hr />
<input type="button" id="percButton" value="Process pending emails" />
<div id="bar" style="border: #000 1px solid; width: 300px;">
</div>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/gauge-bar.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.6.4.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/json2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.signalr.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/signalr/hubs")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/simple-gauge-bar.js")" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var bookingHub = $.connection.bookingHub;
$("#percButton").click(function () {
bookingHub.processPendingEmails();
});
$("#bookButton").click(function () {
bookingHub.bookFlight("fco", "jfk");
});
bookinghub.updategaugebar = function (perc) {
$("#bar").html(gaugebar.generate(perc));
};
bookinghub.displaymessage = function (message) {
$("#msg").html(message);
};
$.connection.hub.start();
});
</script>
My Hub code:
public class BookingHub : Hub
{
public void Send(String message)
{
// Call the addMessage method on all clients.
Clients.displayMessage(message);
}
public void BookFlight(String from, String to)
{
// Book first leg
Clients.displayMessage(String.Format("Booking flight: {0}-{1} ...", from, to));
Thread.Sleep(2000);
// Book return
Clients.displayMessage(String.Format("Booking flight: {0}-{1} ...", to, from));
Thread.Sleep(3000);
// Book return
Clients.displayMessage(String.Format("Booking flight: {0}-{1} ...", to, from));
Thread.Sleep(2000);
// Some return value
Clients.displayMessage("Flight booked successfully.");
}
public void ProcessPendingEmails()
{
Clients.updateGaugeBar(10);
Thread.Sleep(2000);
Clients.updateGaugeBar(40);
Thread.Sleep(3000);
Clients.updateGaugeBar(64);
Thread.Sleep(2000);
Clients.updateGaugeBar(77);
Thread.Sleep(2000);
Clients.updateGaugeBar(92);
Thread.Sleep(3000);
Clients.updateGaugeBar(99);
Thread.Sleep(2000);
Clients.updateGaugeBar(100);
}
}
When I ran the project, I noticed the bookingHub is undefined, and I've got null reference errors at this point.
What Am I doing wrong to get this error?
Thanks in advance.
Are you missing the attribute,
[HubName("bookingHub")]
on your BookingHub class? e.g.
[HubName("bookingHub")]
public class BookingHub : Hub
{
public void Send(String message)
{
// Call the addMessage method on all clients.
Clients.displayMessage(message);
}
...
Add Global.asax to your web app and add this to global.ajax.cs:
namespace SampleWebApplication
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
}
}
}
See https://github.com/SignalR/SignalR/wiki/QuickStart-Hubs