Restructure samples
This commit is contained in:
71
samples/misc/grails3/build.gradle
Normal file
71
samples/misc/grails3/build.gradle
Normal file
@@ -0,0 +1,71 @@
|
||||
buildscript {
|
||||
ext {
|
||||
grailsVersion = project.grailsVersion
|
||||
}
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url "https://repo.grails.org/grails/core" }
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
|
||||
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0"
|
||||
classpath "org.grails.plugins:hibernate4:5.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "eclipse"
|
||||
apply plugin: "idea"
|
||||
apply plugin: "war"
|
||||
apply plugin: "org.grails.grails-web"
|
||||
apply plugin: "org.grails.grails-gsp"
|
||||
apply plugin: "asset-pipeline"
|
||||
apply from: SAMPLE_GRADLE
|
||||
|
||||
ext {
|
||||
grailsVersion = project.grailsVersion
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url "https://repo.grails.org/grails/core" }
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "org.grails:grails-bom:$grailsVersion"
|
||||
}
|
||||
applyMavenExclusions false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.springframework.boot:spring-boot-starter-logging"
|
||||
compile "org.springframework.boot:spring-boot-autoconfigure"
|
||||
compile "org.grails:grails-core"
|
||||
compile "org.springframework.boot:spring-boot-starter-actuator"
|
||||
compile "org.springframework.boot:spring-boot-starter-tomcat"
|
||||
compile "org.grails:grails-dependencies"
|
||||
compile "org.grails:grails-web-boot"
|
||||
compile "org.grails.plugins:cache"
|
||||
compile "org.grails.plugins:scaffolding"
|
||||
compile "org.grails.plugins:hibernate4"
|
||||
compile "org.hibernate:hibernate-ehcache"
|
||||
console "org.grails:grails-console"
|
||||
profile "org.grails.profiles:web:3.1.4"
|
||||
runtime "org.grails.plugins:asset-pipeline"
|
||||
runtime "com.h2database:h2"
|
||||
testCompile "org.grails:grails-plugin-testing"
|
||||
testCompile "org.grails.plugins:geb"
|
||||
testCompile "org.assertj:assertj-core:$assertjVersion"
|
||||
testCompile "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
|
||||
testCompile "net.sourceforge.htmlunit:htmlunit:2.18"
|
||||
|
||||
compile "org.springframework.boot:spring-boot-starter-data-redis"
|
||||
compile 'org.springframework.session:spring-session:1.1.1.RELEASE'
|
||||
|
||||
compile 'org.grails.plugins:spring-security-core:3.0.4'
|
||||
}
|
||||
|
||||
assets {
|
||||
minifyJs = true
|
||||
minifyCss = true
|
||||
}
|
||||
1
samples/misc/grails3/gradle.properties
Normal file
1
samples/misc/grails3/gradle.properties
Normal file
@@ -0,0 +1 @@
|
||||
grailsVersion=3.1.4
|
||||
28
samples/misc/grails3/grails-app/conf/application.groovy
Normal file
28
samples/misc/grails3/grails-app/conf/application.groovy
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
|
||||
// Added by the Spring Security Core plugin:
|
||||
grails.plugin.springsecurity.userLookup.userDomainClassName = 'grails3.redis.session.User'
|
||||
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'grails3.redis.session.UserRole'
|
||||
grails.plugin.springsecurity.authority.className = 'grails3.redis.session.Role'
|
||||
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
|
||||
[pattern: '/', access: ['permitAll']],
|
||||
[pattern: '/error', access: ['permitAll']],
|
||||
[pattern: '/index', access: ['permitAll']],
|
||||
[pattern: '/index.gsp', access: ['permitAll']],
|
||||
[pattern: '/shutdown', access: ['permitAll']],
|
||||
[pattern: '/assets/**', access: ['permitAll']],
|
||||
[pattern: '/**/js/**', access: ['permitAll']],
|
||||
[pattern: '/**/css/**', access: ['permitAll']],
|
||||
[pattern: '/**/images/**', access: ['permitAll']],
|
||||
[pattern: '/**/favicon.ico', access: ['permitAll']]
|
||||
]
|
||||
|
||||
grails.plugin.springsecurity.filterChain.chainMap = [
|
||||
[pattern: '/assets/**', filters: 'none'],
|
||||
[pattern: '/**/js/**', filters: 'none'],
|
||||
[pattern: '/**/css/**', filters: 'none'],
|
||||
[pattern: '/**/images/**', filters: 'none'],
|
||||
[pattern: '/**/favicon.ico', filters: 'none'],
|
||||
[pattern: '/**', filters: 'JOINED_FILTERS']
|
||||
]
|
||||
|
||||
122
samples/misc/grails3/grails-app/conf/application.yml
Normal file
122
samples/misc/grails3/grails-app/conf/application.yml
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
hibernate:
|
||||
cache:
|
||||
queries: false
|
||||
use_second_level_cache: true
|
||||
use_query_cache: false
|
||||
region.factory_class: 'org.hibernate.cache.ehcache.EhCacheRegionFactory'
|
||||
|
||||
dataSource:
|
||||
pooled: true
|
||||
jmxExport: true
|
||||
driverClassName: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
|
||||
environments:
|
||||
development:
|
||||
dataSource:
|
||||
dbCreate: create-drop
|
||||
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
|
||||
test:
|
||||
dataSource:
|
||||
dbCreate: update
|
||||
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
|
||||
production:
|
||||
dataSource:
|
||||
dbCreate: update
|
||||
url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
|
||||
properties:
|
||||
jmxEnabled: true
|
||||
initialSize: 5
|
||||
maxActive: 50
|
||||
minIdle: 5
|
||||
maxIdle: 25
|
||||
maxWait: 10000
|
||||
maxAge: 600000
|
||||
timeBetweenEvictionRunsMillis: 5000
|
||||
minEvictableIdleTimeMillis: 60000
|
||||
validationQuery: SELECT 1
|
||||
validationQueryTimeout: 3
|
||||
validationInterval: 15000
|
||||
testOnBorrow: true
|
||||
testWhileIdle: true
|
||||
testOnReturn: false
|
||||
jdbcInterceptors: ConnectionState
|
||||
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
|
||||
|
||||
---
|
||||
---
|
||||
grails:
|
||||
profile: web
|
||||
codegen:
|
||||
defaultPackage: grails3.redis.session
|
||||
spring:
|
||||
transactionManagement:
|
||||
proxies: false
|
||||
info:
|
||||
app:
|
||||
name: '@info.app.name@'
|
||||
version: '@info.app.version@'
|
||||
grailsVersion: '@info.app.grailsVersion@'
|
||||
spring:
|
||||
|
||||
groovy:
|
||||
template:
|
||||
check-template-location: false
|
||||
|
||||
---
|
||||
grails:
|
||||
mime:
|
||||
disable:
|
||||
accept:
|
||||
header:
|
||||
userAgents:
|
||||
- Gecko
|
||||
- WebKit
|
||||
- Presto
|
||||
- Trident
|
||||
types:
|
||||
all: '*/*'
|
||||
atom: application/atom+xml
|
||||
css: text/css
|
||||
csv: text/csv
|
||||
form: application/x-www-form-urlencoded
|
||||
html:
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
js: text/javascript
|
||||
json:
|
||||
- application/json
|
||||
- text/json
|
||||
multipartForm: multipart/form-data
|
||||
pdf: application/pdf
|
||||
rss: application/rss+xml
|
||||
text: text/plain
|
||||
hal:
|
||||
- application/hal+json
|
||||
- application/hal+xml
|
||||
xml:
|
||||
- text/xml
|
||||
- application/xml
|
||||
urlmapping:
|
||||
cache:
|
||||
maxsize: 1000
|
||||
controllers:
|
||||
defaultScope: singleton
|
||||
converters:
|
||||
encoding: UTF-8
|
||||
views:
|
||||
default:
|
||||
codec: html
|
||||
gsp:
|
||||
encoding: UTF-8
|
||||
htmlcodec: xml
|
||||
codecs:
|
||||
expression: html
|
||||
scriptlets: html
|
||||
taglib: none
|
||||
staticparts: none
|
||||
endpoints:
|
||||
jmx:
|
||||
unique-names: true
|
||||
23
samples/misc/grails3/grails-app/conf/logback.groovy
Normal file
23
samples/misc/grails3/grails-app/conf/logback.groovy
Normal file
@@ -0,0 +1,23 @@
|
||||
import grails.util.BuildSettings
|
||||
import grails.util.Environment
|
||||
|
||||
// See http://logback.qos.ch/manual/groovy.html for details on configuration
|
||||
appender('STDOUT', ConsoleAppender) {
|
||||
encoder(PatternLayoutEncoder) {
|
||||
pattern = "%level %logger - %msg%n"
|
||||
}
|
||||
}
|
||||
|
||||
root(ERROR, ['STDOUT'])
|
||||
|
||||
def targetDir = BuildSettings.TARGET_DIR
|
||||
if (Environment.isDevelopmentMode() && targetDir) {
|
||||
appender("FULL_STACKTRACE", FileAppender) {
|
||||
file = "${targetDir}/stacktrace.log"
|
||||
append = true
|
||||
encoder(PatternLayoutEncoder) {
|
||||
pattern = "%level %logger - %msg%n"
|
||||
}
|
||||
}
|
||||
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// Place your Spring DSL code here
|
||||
beans = {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import grails.plugin.springsecurity.annotation.Secured
|
||||
|
||||
class TestController {
|
||||
@Secured('ROLE_ADMIN')
|
||||
def index() { } // Renders `test/index.gsp`
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package grails3.redis.session
|
||||
|
||||
class UrlMappings {
|
||||
|
||||
static mappings = {
|
||||
"/$controller/$action?/$id?(.$format)?"{
|
||||
constraints {
|
||||
// apply constraints here
|
||||
}
|
||||
}
|
||||
|
||||
"/"(view:"/index")
|
||||
"500"(view:'/error')
|
||||
"404"(view:'/notFound')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
@EqualsAndHashCode(includes='authority')
|
||||
@ToString(includes='authority', includeNames=true, includePackage=false)
|
||||
class Role implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1
|
||||
|
||||
String authority
|
||||
|
||||
Role(String authority) {
|
||||
this()
|
||||
this.authority = authority
|
||||
}
|
||||
|
||||
static constraints = {
|
||||
authority blank: false, unique: true
|
||||
}
|
||||
|
||||
static mapping = {
|
||||
cache true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
@EqualsAndHashCode(includes='username')
|
||||
@ToString(includes='username', includeNames=true, includePackage=false)
|
||||
class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1
|
||||
|
||||
transient springSecurityService
|
||||
|
||||
String username
|
||||
String password
|
||||
boolean enabled = true
|
||||
boolean accountExpired
|
||||
boolean accountLocked
|
||||
boolean passwordExpired
|
||||
|
||||
User(String username, String password) {
|
||||
this()
|
||||
this.username = username
|
||||
this.password = password
|
||||
}
|
||||
|
||||
Set<Role> getAuthorities() {
|
||||
UserRole.findAllByUser(this)*.role
|
||||
}
|
||||
|
||||
def beforeInsert() {
|
||||
encodePassword()
|
||||
}
|
||||
|
||||
def beforeUpdate() {
|
||||
if (isDirty('password')) {
|
||||
encodePassword()
|
||||
}
|
||||
}
|
||||
|
||||
protected void encodePassword() {
|
||||
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
|
||||
}
|
||||
|
||||
static transients = ['springSecurityService']
|
||||
|
||||
static constraints = {
|
||||
password blank: false, password: true
|
||||
username blank: false, unique: true
|
||||
}
|
||||
|
||||
static mapping = {
|
||||
password column: '`password`'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import grails.gorm.DetachedCriteria
|
||||
import groovy.transform.ToString
|
||||
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder
|
||||
|
||||
@ToString(cache=true, includeNames=true, includePackage=false)
|
||||
class UserRole implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1
|
||||
|
||||
User user
|
||||
Role role
|
||||
|
||||
UserRole(User u, Role r) {
|
||||
this()
|
||||
user = u
|
||||
role = r
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean equals(other) {
|
||||
if (!(other instanceof UserRole)) {
|
||||
return false
|
||||
}
|
||||
|
||||
other.user?.id == user?.id && other.role?.id == role?.id
|
||||
}
|
||||
|
||||
@Override
|
||||
int hashCode() {
|
||||
def builder = new HashCodeBuilder()
|
||||
if (user) builder.append(user.id)
|
||||
if (role) builder.append(role.id)
|
||||
builder.toHashCode()
|
||||
}
|
||||
|
||||
static UserRole get(long userId, long roleId) {
|
||||
criteriaFor(userId, roleId).get()
|
||||
}
|
||||
|
||||
static boolean exists(long userId, long roleId) {
|
||||
criteriaFor(userId, roleId).count()
|
||||
}
|
||||
|
||||
private static DetachedCriteria criteriaFor(long userId, long roleId) {
|
||||
UserRole.where {
|
||||
user == User.load(userId) &&
|
||||
role == Role.load(roleId)
|
||||
}
|
||||
}
|
||||
|
||||
static UserRole create(User user, Role role, boolean flush = false) {
|
||||
def instance = new UserRole(user: user, role: role)
|
||||
instance.save(flush: flush, insert: true)
|
||||
instance
|
||||
}
|
||||
|
||||
static boolean remove(User u, Role r, boolean flush = false) {
|
||||
if (u == null || r == null) return false
|
||||
|
||||
int rowCount = UserRole.where { user == u && role == r }.deleteAll()
|
||||
|
||||
if (flush) { UserRole.withSession { it.flush() } }
|
||||
|
||||
rowCount
|
||||
}
|
||||
|
||||
static void removeAll(User u, boolean flush = false) {
|
||||
if (u == null) return
|
||||
|
||||
UserRole.where { user == u }.deleteAll()
|
||||
|
||||
if (flush) { UserRole.withSession { it.flush() } }
|
||||
}
|
||||
|
||||
static void removeAll(Role r, boolean flush = false) {
|
||||
if (r == null) return
|
||||
|
||||
UserRole.where { role == r }.deleteAll()
|
||||
|
||||
if (flush) { UserRole.withSession { it.flush() } }
|
||||
}
|
||||
|
||||
static constraints = {
|
||||
role validator: { Role r, UserRole ur ->
|
||||
if (ur.user == null || ur.user.id == null) return
|
||||
boolean existing = false
|
||||
UserRole.withNewSession {
|
||||
existing = UserRole.exists(ur.user.id, r.id)
|
||||
}
|
||||
if (existing) {
|
||||
return 'userRole.exists'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mapping = {
|
||||
id composite: ['user', 'role']
|
||||
version false
|
||||
}
|
||||
}
|
||||
56
samples/misc/grails3/grails-app/i18n/messages.properties
Normal file
56
samples/misc/grails3/grails-app/i18n/messages.properties
Normal file
@@ -0,0 +1,56 @@
|
||||
default.doesnt.match.message=Property [{0}] of class [{1}] with value [{2}] does not match the required pattern [{3}]
|
||||
default.invalid.url.message=Property [{0}] of class [{1}] with value [{2}] is not a valid URL
|
||||
default.invalid.creditCard.message=Property [{0}] of class [{1}] with value [{2}] is not a valid credit card number
|
||||
default.invalid.email.message=Property [{0}] of class [{1}] with value [{2}] is not a valid e-mail address
|
||||
default.invalid.range.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid range from [{3}] to [{4}]
|
||||
default.invalid.size.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}]
|
||||
default.invalid.max.message=Property [{0}] of class [{1}] with value [{2}] exceeds maximum value [{3}]
|
||||
default.invalid.min.message=Property [{0}] of class [{1}] with value [{2}] is less than minimum value [{3}]
|
||||
default.invalid.max.size.message=Property [{0}] of class [{1}] with value [{2}] exceeds the maximum size of [{3}]
|
||||
default.invalid.min.size.message=Property [{0}] of class [{1}] with value [{2}] is less than the minimum size of [{3}]
|
||||
default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation
|
||||
default.not.inlist.message=Property [{0}] of class [{1}] with value [{2}] is not contained within the list [{3}]
|
||||
default.blank.message=Property [{0}] of class [{1}] cannot be blank
|
||||
default.not.equal.message=Property [{0}] of class [{1}] with value [{2}] cannot equal [{3}]
|
||||
default.null.message=Property [{0}] of class [{1}] cannot be null
|
||||
default.not.unique.message=Property [{0}] of class [{1}] with value [{2}] must be unique
|
||||
|
||||
default.paginate.prev=Previous
|
||||
default.paginate.next=Next
|
||||
default.boolean.true=True
|
||||
default.boolean.false=False
|
||||
default.date.format=yyyy-MM-dd HH:mm:ss z
|
||||
default.number.format=0
|
||||
|
||||
default.created.message={0} {1} created
|
||||
default.updated.message={0} {1} updated
|
||||
default.deleted.message={0} {1} deleted
|
||||
default.not.deleted.message={0} {1} could not be deleted
|
||||
default.not.found.message={0} not found with id {1}
|
||||
default.optimistic.locking.failure=Another user has updated this {0} while you were editing
|
||||
|
||||
default.home.label=Home
|
||||
default.list.label={0} List
|
||||
default.add.label=Add {0}
|
||||
default.new.label=New {0}
|
||||
default.create.label=Create {0}
|
||||
default.show.label=Show {0}
|
||||
default.edit.label=Edit {0}
|
||||
|
||||
default.button.create.label=Create
|
||||
default.button.edit.label=Edit
|
||||
default.button.update.label=Update
|
||||
default.button.delete.label=Delete
|
||||
default.button.delete.confirm.message=Are you sure?
|
||||
|
||||
# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author)
|
||||
typeMismatch.java.net.URL=Property {0} must be a valid URL
|
||||
typeMismatch.java.net.URI=Property {0} must be a valid URI
|
||||
typeMismatch.java.util.Date=Property {0} must be a valid Date
|
||||
typeMismatch.java.lang.Double=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Integer=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Long=Property {0} must be a valid number
|
||||
typeMismatch.java.lang.Short=Property {0} must be a valid number
|
||||
typeMismatch.java.math.BigDecimal=Property {0} must be a valid number
|
||||
typeMismatch.java.math.BigInteger=Property {0} must be a valid number
|
||||
typeMismatch=Property {0} is type-mismatched
|
||||
24
samples/misc/grails3/grails-app/init/BootStrap.groovy
Normal file
24
samples/misc/grails3/grails-app/init/BootStrap.groovy
Normal file
@@ -0,0 +1,24 @@
|
||||
import grails3.redis.session.*
|
||||
|
||||
class BootStrap {
|
||||
|
||||
def init = { servletContext ->
|
||||
def adminRole = new Role('ROLE_ADMIN').save()
|
||||
def userRole = new Role('ROLE_USER').save()
|
||||
|
||||
def testUser = new User('user', 'password').save()
|
||||
|
||||
UserRole.create testUser, adminRole
|
||||
|
||||
UserRole.withSession {
|
||||
it.flush()
|
||||
it.clear()
|
||||
}
|
||||
|
||||
assert User.count() == 1
|
||||
assert Role.count() == 2
|
||||
assert UserRole.count() == 1
|
||||
}
|
||||
def destroy = {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package grails3.redis.session
|
||||
|
||||
import grails.boot.GrailsApp
|
||||
import grails.boot.config.GrailsAutoConfiguration
|
||||
|
||||
class Application extends GrailsAutoConfiguration {
|
||||
static void main(String[] args) {
|
||||
GrailsApp.run(Application, args)
|
||||
}
|
||||
}
|
||||
31
samples/misc/grails3/grails-app/views/error.gsp
Normal file
31
samples/misc/grails3/grails-app/views/error.gsp
Normal file
@@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title><g:if env="development">Grails Runtime Exception</g:if><g:else>Error</g:else></title>
|
||||
<meta name="layout" content="main">
|
||||
<g:if env="development"><asset:stylesheet src="errors.css"/></g:if>
|
||||
</head>
|
||||
<body>
|
||||
<g:if env="development">
|
||||
<g:if test="${Throwable.isInstance(exception)}">
|
||||
<g:renderException exception="${exception}" />
|
||||
</g:if>
|
||||
<g:elseif test="${request.getAttribute('javax.servlet.error.exception')}">
|
||||
<g:renderException exception="${request.getAttribute('javax.servlet.error.exception')}" />
|
||||
</g:elseif>
|
||||
<g:else>
|
||||
<ul class="errors">
|
||||
<li>An error has occurred</li>
|
||||
<li>Exception: ${exception}</li>
|
||||
<li>Message: ${message}</li>
|
||||
<li>Path: ${path}</li>
|
||||
</ul>
|
||||
</g:else>
|
||||
</g:if>
|
||||
<g:else>
|
||||
<ul class="errors">
|
||||
<li>An error has occurred</li>
|
||||
</ul>
|
||||
</g:else>
|
||||
</body>
|
||||
</html>
|
||||
8
samples/misc/grails3/grails-app/views/index.gsp
Normal file
8
samples/misc/grails3/grails-app/views/index.gsp
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Index</title>
|
||||
</head>
|
||||
<body>
|
||||
Left blank, goto <a href="/test">test</a>
|
||||
</body>
|
||||
</html>
|
||||
14
samples/misc/grails3/grails-app/views/notFound.gsp
Normal file
14
samples/misc/grails3/grails-app/views/notFound.gsp
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Page Not Found</title>
|
||||
<meta name="layout" content="main">
|
||||
<g:if env="development"><asset:stylesheet src="errors.css"/></g:if>
|
||||
</head>
|
||||
<body>
|
||||
<ul class="errors">
|
||||
<li>Error: Page Not Found (404)</li>
|
||||
<li>Path: ${request.forwardURI}</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
16
samples/misc/grails3/grails-app/views/test/index.gsp
Normal file
16
samples/misc/grails3/grails-app/views/test/index.gsp
Normal file
@@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Home Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="un">
|
||||
<sec:loggedInUserInfo field='username'/>
|
||||
</div>
|
||||
<div id="session">
|
||||
${session.id}
|
||||
</div>
|
||||
<form action="/logout" method="post">
|
||||
<input type="submit" value="Log Out"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample
|
||||
|
||||
import grails.test.mixin.integration.Integration
|
||||
import grails.transaction.Transactional
|
||||
import org.springframework.boot.test.IntegrationTest
|
||||
|
||||
import spock.lang.*
|
||||
import geb.spock.*
|
||||
|
||||
import sample.pages.HomePage
|
||||
import sample.pages.LoginPage
|
||||
import sample.pages.IndexPage
|
||||
import spock.lang.Stepwise
|
||||
import pages.*
|
||||
|
||||
/**
|
||||
* Functional tests for grails 3 and spring-session
|
||||
*
|
||||
* @author Eric Helgeson
|
||||
*/
|
||||
|
||||
@Stepwise
|
||||
@IntegrationTest("server.port:0")
|
||||
@Integration(applicationClass=grails3.redis.session.Application)
|
||||
class HomeSpec extends GebSpec {
|
||||
|
||||
def setup() {
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
}
|
||||
|
||||
void 'Anonymous page not redirected to login'() {
|
||||
when: 'The index page is visited'
|
||||
go '/'
|
||||
|
||||
then: 'Not redirected'
|
||||
at IndexPage
|
||||
}
|
||||
|
||||
void 'Unauthenticated user sent to log in page'() {
|
||||
when: 'The test page is visited'
|
||||
go '/test/index'
|
||||
if(title != 'Login') {
|
||||
println driver.pageSource
|
||||
}
|
||||
|
||||
then: 'The password form is correct'
|
||||
title == 'Login'
|
||||
$('#password')
|
||||
$('#username')
|
||||
}
|
||||
|
||||
void 'Log in views home page'() {
|
||||
when: 'log in successfully'
|
||||
to LoginPage
|
||||
login()
|
||||
|
||||
then: 'sent to original page'
|
||||
at HomePage
|
||||
|
||||
and: 'the username is displayed'
|
||||
username == 'user'
|
||||
|
||||
and: 'session id is not blank'
|
||||
session != ''
|
||||
|
||||
and: 'Spring Session Management is being used'
|
||||
driver.manage().cookies.find { it.name == 'SESSION' }
|
||||
|
||||
and: 'Standard Session is NOT being used'
|
||||
!driver.manage().cookies.find { it.name == 'JSESSIONID' }
|
||||
}
|
||||
|
||||
def 'Log out success'() {
|
||||
when:
|
||||
logout()
|
||||
|
||||
then:
|
||||
at IndexPage
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.pages
|
||||
|
||||
import geb.*
|
||||
|
||||
/**
|
||||
* The home page
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class HomePage extends Page {
|
||||
static url = '/test'
|
||||
static at = { assert driver.title == 'Home Page'; true}
|
||||
static content = {
|
||||
username { $('#un').text() }
|
||||
session { $('#session').text() }
|
||||
logout(to:LoginPage) { $('input[type=submit]').click() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.pages
|
||||
|
||||
import geb.*
|
||||
|
||||
/**
|
||||
* The Index page
|
||||
*
|
||||
* @author Eric Helgeson
|
||||
*/
|
||||
class IndexPage extends Page {
|
||||
static url = '/'
|
||||
static at = { assert driver.title == 'Index'; true}
|
||||
static content = { }
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.pages
|
||||
|
||||
import geb.*
|
||||
|
||||
/**
|
||||
* The Login Page
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class LoginPage extends Page {
|
||||
static url = '/login'
|
||||
static at = { assert driver.title == 'Login'; true}
|
||||
static content = {
|
||||
form { $('form') }
|
||||
submit { $('input[type=submit]') }
|
||||
login(required:false) { user='user', pass='password' ->
|
||||
form.username = user
|
||||
form.password = pass
|
||||
submit.click()
|
||||
}
|
||||
}
|
||||
}
|
||||
18
samples/misc/hazelcast/build.gradle
Normal file
18
samples/misc/hazelcast/build.gradle
Normal file
@@ -0,0 +1,18 @@
|
||||
apply from: JAVA_GRADLE
|
||||
apply from: TOMCAT_7_GRADLE
|
||||
apply from: SAMPLE_GRADLE
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-session'),
|
||||
"org.webjars:bootstrap:$bootstrapVersion",
|
||||
"org.webjars:webjars-taglib:$webjarsTaglibVersion",
|
||||
"com.hazelcast:hazelcast-client:$hazelcastVersion",
|
||||
jstlDependencies
|
||||
|
||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||
|
||||
testCompile "junit:junit:$junitVersion",
|
||||
"org.assertj:assertj-core:$assertjVersion"
|
||||
|
||||
integrationTestCompile seleniumDependencies
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
|
||||
import sample.pages.HomePage;
|
||||
import sample.pages.HomePage.Attribute;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Eddú Meléndez
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class AttributeTests {
|
||||
|
||||
private WebDriver driver;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.driver = new HtmlUnitDriver();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
this.driver.quit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void home() {
|
||||
HomePage home = HomePage.go(this.driver);
|
||||
home.assertAt();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noAttributes() {
|
||||
HomePage home = HomePage.go(this.driver);
|
||||
assertThat(home.attributes().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAttribute() {
|
||||
HomePage home = HomePage.go(this.driver);
|
||||
// @formatter:off
|
||||
home = home.form()
|
||||
.attributeName("a")
|
||||
.attributeValue("b")
|
||||
.submit(HomePage.class);
|
||||
// @formatter:on
|
||||
|
||||
List<Attribute> attributes = home.attributes();
|
||||
assertThat(attributes).hasSize(1);
|
||||
Attribute row = attributes.get(0);
|
||||
assertThat(row.getAttributeName()).isEqualTo("a");
|
||||
assertThat(row.getAttributeValue()).isEqualTo("b");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.pages;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.openqa.selenium.SearchContext;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Eddú Meléndez
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class HomePage {
|
||||
|
||||
private WebDriver driver;
|
||||
|
||||
@FindBy(css = "form")
|
||||
WebElement form;
|
||||
|
||||
@FindBy(css = "table tbody tr")
|
||||
List<WebElement> trs;
|
||||
|
||||
List<Attribute> attributes;
|
||||
|
||||
public HomePage(WebDriver driver) {
|
||||
this.driver = driver;
|
||||
this.attributes = new ArrayList<Attribute>();
|
||||
}
|
||||
|
||||
private static void get(WebDriver driver, String get) {
|
||||
String baseUrl = "http://localhost:" + System.getProperty("tomcat.port", "8080");
|
||||
driver.get(baseUrl + get);
|
||||
}
|
||||
|
||||
public static HomePage go(WebDriver driver) {
|
||||
get(driver, "/");
|
||||
return PageFactory.initElements(driver, HomePage.class);
|
||||
}
|
||||
|
||||
public void assertAt() {
|
||||
assertThat(this.driver.getTitle()).isEqualTo("Session Attributes");
|
||||
}
|
||||
|
||||
public List<Attribute> attributes() {
|
||||
List<Attribute> rows = new ArrayList<Attribute>();
|
||||
for (WebElement tr : this.trs) {
|
||||
rows.add(new Attribute(tr));
|
||||
}
|
||||
this.attributes.addAll(rows);
|
||||
return this.attributes;
|
||||
}
|
||||
|
||||
public Form form() {
|
||||
return new Form(this.form);
|
||||
}
|
||||
|
||||
public class Form {
|
||||
@FindBy(name = "attributeName")
|
||||
WebElement attributeName;
|
||||
|
||||
@FindBy(name = "attributeValue")
|
||||
WebElement attributeValue;
|
||||
|
||||
@FindBy(css = "input[type=\"submit\"]")
|
||||
WebElement submit;
|
||||
|
||||
public Form(SearchContext context) {
|
||||
PageFactory.initElements(new DefaultElementLocatorFactory(context), this);
|
||||
}
|
||||
|
||||
public Form attributeName(String text) {
|
||||
this.attributeName.sendKeys(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Form attributeValue(String text) {
|
||||
this.attributeValue.sendKeys(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> T submit(Class<T> page) {
|
||||
this.submit.click();
|
||||
return PageFactory.initElements(HomePage.this.driver, page);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Attribute {
|
||||
@FindBy(xpath = ".//td[1]")
|
||||
WebElement attributeName;
|
||||
|
||||
@FindBy(xpath = ".//td[2]")
|
||||
WebElement attributeValue;
|
||||
|
||||
public Attribute(SearchContext context) {
|
||||
PageFactory.initElements(new DefaultElementLocatorFactory(context), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attributeName
|
||||
*/
|
||||
public String getAttributeName() {
|
||||
return this.attributeName.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attributeValue
|
||||
*/
|
||||
public String getAttributeValue() {
|
||||
return this.attributeValue.getText();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
96
samples/misc/hazelcast/src/main/java/sample/Initializer.java
Normal file
96
samples/misc/hazelcast/src/main/java/sample/Initializer.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.FilterRegistration.Dynamic;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.annotation.WebListener;
|
||||
|
||||
import com.hazelcast.config.Config;
|
||||
import com.hazelcast.config.MapConfig;
|
||||
import com.hazelcast.config.NetworkConfig;
|
||||
import com.hazelcast.config.SerializerConfig;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
|
||||
import org.springframework.session.ExpiringSession;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.MapSessionRepository;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
|
||||
@WebListener
|
||||
public class Initializer implements ServletContextListener {
|
||||
private HazelcastInstance instance;
|
||||
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
String sessionMapName = "spring:session:sessions";
|
||||
ServletContext sc = sce.getServletContext();
|
||||
|
||||
Config cfg = new Config();
|
||||
NetworkConfig netConfig = new NetworkConfig();
|
||||
netConfig.setPort(getAvailablePort());
|
||||
cfg.setNetworkConfig(netConfig);
|
||||
SerializerConfig serializer = new SerializerConfig().setTypeClass(Object.class)
|
||||
.setImplementation(new ObjectStreamSerializer());
|
||||
cfg.getSerializationConfig().addSerializerConfig(serializer);
|
||||
MapConfig mc = new MapConfig();
|
||||
mc.setName(sessionMapName);
|
||||
mc.setTimeToLiveSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);
|
||||
cfg.addMapConfig(mc);
|
||||
|
||||
this.instance = Hazelcast.newHazelcastInstance(cfg);
|
||||
Map<String, ExpiringSession> sessions = this.instance.getMap(sessionMapName);
|
||||
|
||||
SessionRepository<ExpiringSession> sessionRepository = new MapSessionRepository(
|
||||
sessions);
|
||||
SessionRepositoryFilter<ExpiringSession> filter = new SessionRepositoryFilter<ExpiringSession>(
|
||||
sessionRepository);
|
||||
Dynamic fr = sc.addFilter("springSessionFilter", filter);
|
||||
fr.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
|
||||
}
|
||||
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
this.instance.shutdown();
|
||||
}
|
||||
|
||||
private static int getAvailablePort() {
|
||||
ServerSocket socket = null;
|
||||
try {
|
||||
socket = new ServerSocket(0);
|
||||
return socket.getLocalPort();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.hazelcast.nio.ObjectDataInput;
|
||||
import com.hazelcast.nio.ObjectDataOutput;
|
||||
import com.hazelcast.nio.serialization.StreamSerializer;
|
||||
|
||||
/**
|
||||
* A {@link StreamSerializer} that uses Java serialization to persist the session. This is
|
||||
* certainly not the most efficient way to persist sessions, but the example is intended
|
||||
* to demonstrate using minimal dependencies. For better serialization methods try using
|
||||
* <a href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
|
||||
*
|
||||
* @author Rob Winch
|
||||
*
|
||||
*/
|
||||
public class ObjectStreamSerializer implements StreamSerializer<Object> {
|
||||
public int getTypeId() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public void write(ObjectDataOutput objectDataOutput, Object object)
|
||||
throws IOException {
|
||||
ObjectOutputStream out = new ObjectOutputStream((OutputStream) objectDataOutput);
|
||||
out.writeObject(object);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public Object read(ObjectDataInput objectDataInput) throws IOException {
|
||||
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
|
||||
try {
|
||||
return in.readObject();
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@WebServlet("/session")
|
||||
public class SessionServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
String attributeName = req.getParameter("attributeName");
|
||||
String attributeValue = req.getParameter("attributeValue");
|
||||
req.getSession().setAttribute(attributeName, attributeValue);
|
||||
resp.sendRedirect(req.getContextPath() + "/");
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 2878267318695777395L;
|
||||
}
|
||||
50
samples/misc/hazelcast/src/main/webapp/index.jsp
Normal file
50
samples/misc/hazelcast/src/main/webapp/index.jsp
Normal file
@@ -0,0 +1,50 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="wj" uri="http://www.webjars.org/tags" %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Session Attributes</title>
|
||||
<wj:locate path="bootstrap.min.css" relativeTo="META-INF/resources" var="bootstrapCssLocation"/>
|
||||
<link rel="stylesheet" href="<c:url value="${bootstrapCssLocation}"/>">
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Description</h1>
|
||||
<p>This application demonstrates how to use Hazelcast to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.</p>
|
||||
|
||||
<h1>Try it</h1>
|
||||
|
||||
<form class="form-inline" role="form" action="./session" method="post">
|
||||
<label for="attributeName">Attribute Name</label>
|
||||
<input id="attributeName" type="text" name="attributeName"/>
|
||||
<label for="attributeValue">Attribute Value</label>
|
||||
<input id="attributeValue" type="text" name="attributeValue"/>
|
||||
<input type="submit" value="Set Attribute"/>
|
||||
</form>
|
||||
|
||||
<hr/>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute Name</th>
|
||||
<th>Attribute Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:forEach items="${sessionScope}" var="attr">
|
||||
<tr>
|
||||
<td><c:out value="${attr.key}"/></td>
|
||||
<td><c:out value="${attr.value}"/></td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user