删除编译错误
This commit is contained in:
parent
f857c68a7c
commit
83883319ab
|
@ -0,0 +1,3 @@
|
|||
## Web
|
||||
|
||||
This module contains web modules.
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles
|
||||
|
||||
- [Intro to Apache Tapestry](https://www.baeldung.com/apache-tapestry)
|
|
@ -0,0 +1,152 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>apache-tapestry</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>apache-tapestry</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- To set up an application with a database, change the artifactId below to tapestry-hibernate, -->
|
||||
<!-- and add a dependency on your JDBC driver. You'll also need to add Hibernate configuration -->
|
||||
<!-- files, such as hibernate.cfg.xml. -->
|
||||
<dependency>
|
||||
<groupId>org.apache.tapestry</groupId>
|
||||
<artifactId>tapestry-core</artifactId>
|
||||
<version>${tapestry.version}</version>
|
||||
</dependency>
|
||||
<!-- Include the Log4j implementation for the SLF4J logging framework -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${slf4j-release-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tapestry</groupId>
|
||||
<artifactId>tapestry-webresources</artifactId>
|
||||
<version>${tapestry.version}</version>
|
||||
</dependency>
|
||||
<!-- Uncomment this to add support for file uploads: -->
|
||||
<!-- <dependency> -->
|
||||
<!-- <groupId>org.apache.tapestry</groupId> -->
|
||||
<!-- <artifactId>tapestry-upload</artifactId> -->
|
||||
<!-- <version>${tapestry.version}</version> -->
|
||||
<!-- </dependency> -->
|
||||
<!-- A dependency on either JUnit or TestNG is required, or the surefire plugin (which runs the -->
|
||||
<!-- tests) will fail, preventing Maven from packaging the WAR. Tapestry includes a large number -->
|
||||
<!-- of testing facilities designed for use with TestNG (http://testng.org/), -->
|
||||
<!-- so it's recommended. -->
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>${testng-release-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tapestry</groupId>
|
||||
<artifactId>tapestry-test</artifactId>
|
||||
<version>${tapestry.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Provided by the servlet container, but sometimes referenced in the application code. -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>${servlet-api-release-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Provide dependency to the Tapestry javadoc taglet which replaces the Maven component report -->
|
||||
<dependency>
|
||||
<groupId>org.apache.tapestry</groupId>
|
||||
<artifactId>tapestry-javadoc</artifactId>
|
||||
<version>${tapestry.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>apache-tapestry</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${compiler.plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${source.version}</source>
|
||||
<target>${target.version}</target>
|
||||
<optimize>true</optimize>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${compiler.surefire.version}</version>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<tapestry.execution-mode>Qa</tapestry.execution-mode>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Run the application using "mvn jetty:run" -->
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>${compiler.jetty.version}</version>
|
||||
<configuration>
|
||||
<!-- Log to the console. -->
|
||||
<requestLog implementation="org.mortbay.jetty.NCSARequestLog">
|
||||
<!-- This doesn't do anything for Jetty, but is a workaround -->
|
||||
<!-- for a Maven bug that prevents the requestLog from being set. -->
|
||||
<append>true</append>
|
||||
</requestLog>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>tapestry.execution-mode</name>
|
||||
<value>development</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jboss</id>
|
||||
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<compiler.jetty.version>6.1.16</compiler.jetty.version>
|
||||
<compiler.surefire.version>3.0.0-M5</compiler.surefire.version>
|
||||
<compiler.plugin.version>3.8.1</compiler.plugin.version>
|
||||
<source.version>11</source.version>
|
||||
<target.version>11</target.version>
|
||||
<tapestry.version>5.8.2</tapestry.version>
|
||||
<servlet-api-release-version>2.5</servlet-api-release-version>
|
||||
<testng-release-version>6.8.21</testng-release-version>
|
||||
<slf4j-release-version>1.7.19</slf4j-release-version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.tapestry.components;
|
||||
|
||||
import org.apache.tapestry5.BindingConstants;
|
||||
import org.apache.tapestry5.annotations.Parameter;
|
||||
import org.apache.tapestry5.annotations.Property;
|
||||
|
||||
/**
|
||||
* Layout component for pages of application.
|
||||
*/
|
||||
public class Layout {
|
||||
|
||||
@Property
|
||||
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
|
||||
private String title;
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.baeldung.tapestry.pages;
|
||||
|
||||
public class Error404 {
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.tapestry.pages;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.tapestry5.Block;
|
||||
import org.apache.tapestry5.annotations.Log;
|
||||
import org.apache.tapestry5.annotations.Property;
|
||||
import org.apache.tapestry5.ioc.annotations.Inject;
|
||||
import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class Home {
|
||||
|
||||
@Property
|
||||
private String appName = "apache-tapestry";
|
||||
|
||||
public Date getCurrentTime() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
@Inject
|
||||
private Logger logger;
|
||||
|
||||
@Inject
|
||||
private AjaxResponseRenderer ajaxResponseRenderer;
|
||||
|
||||
@Inject
|
||||
private Block ajaxBlock;
|
||||
|
||||
@Log
|
||||
void onCallAjax() {
|
||||
logger.info("Ajax call");
|
||||
ajaxResponseRenderer.addRender("ajaxZone", ajaxBlock);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.baeldung.tapestry.pages;
|
||||
|
||||
|
||||
import org.apache.tapestry5.Block;
|
||||
import org.apache.tapestry5.EventContext;
|
||||
import org.apache.tapestry5.SymbolConstants;
|
||||
import org.apache.tapestry5.annotations.InjectPage;
|
||||
import org.apache.tapestry5.annotations.Log;
|
||||
import org.apache.tapestry5.annotations.Property;
|
||||
import org.apache.tapestry5.ioc.annotations.Inject;
|
||||
import org.apache.tapestry5.ioc.annotations.Symbol;
|
||||
import org.apache.tapestry5.services.HttpError;
|
||||
import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Start page of application apache-tapestry.
|
||||
*/
|
||||
public class Index {
|
||||
@Inject
|
||||
private Logger logger;
|
||||
|
||||
@Inject
|
||||
private AjaxResponseRenderer ajaxResponseRenderer;
|
||||
|
||||
@Property
|
||||
@Inject
|
||||
@Symbol(SymbolConstants.TAPESTRY_VERSION)
|
||||
private String tapestryVersion;
|
||||
|
||||
@Inject
|
||||
private Block block;
|
||||
|
||||
// Handle call with an unwanted context
|
||||
Object onActivate(EventContext eventContext) {
|
||||
return eventContext.getCount() > 0 ?
|
||||
new HttpError(404, "Resource not found") :
|
||||
null;
|
||||
}
|
||||
|
||||
@Log
|
||||
void onComplete() {
|
||||
logger.info("Complete call on Index page");
|
||||
}
|
||||
|
||||
@Log
|
||||
void onAjax() {
|
||||
logger.info("Ajax call on Index page");
|
||||
|
||||
ajaxResponseRenderer.addRender("middlezone", block);
|
||||
}
|
||||
|
||||
public Date getCurrentTime() {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.tapestry.pages;
|
||||
|
||||
import org.apache.tapestry5.alerts.AlertManager;
|
||||
import org.apache.tapestry5.annotations.InjectComponent;
|
||||
import org.apache.tapestry5.annotations.Property;
|
||||
import org.apache.tapestry5.corelib.components.Form;
|
||||
import org.apache.tapestry5.ioc.annotations.Inject;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class Login {
|
||||
@Inject
|
||||
private Logger logger;
|
||||
|
||||
@Inject
|
||||
private AlertManager alertManager;
|
||||
|
||||
@InjectComponent
|
||||
private Form login;
|
||||
|
||||
@Property
|
||||
private String email;
|
||||
|
||||
@Property
|
||||
private String password;
|
||||
|
||||
void onValidateFromLogin() {
|
||||
if(email == null || password == null) {
|
||||
alertManager.error("Email/Password is null");
|
||||
login.recordError("Validation failed");
|
||||
}
|
||||
}
|
||||
|
||||
Object onSuccessFromLogin() {
|
||||
alertManager.success("Welcome! Login Successful");
|
||||
return Home.class;
|
||||
}
|
||||
|
||||
void onFailureFromLogin() {
|
||||
alertManager.error("Please try again with correct credentials");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package com.baeldung.tapestry.services;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tapestry5.SymbolConstants;
|
||||
import org.apache.tapestry5.commons.MappedConfiguration;
|
||||
import org.apache.tapestry5.commons.OrderedConfiguration;
|
||||
import org.apache.tapestry5.http.services.Request;
|
||||
import org.apache.tapestry5.http.services.RequestFilter;
|
||||
import org.apache.tapestry5.http.services.RequestHandler;
|
||||
import org.apache.tapestry5.http.services.Response;
|
||||
import org.apache.tapestry5.ioc.ServiceBinder;
|
||||
import org.apache.tapestry5.ioc.annotations.Contribute;
|
||||
import org.apache.tapestry5.ioc.annotations.Local;
|
||||
import org.apache.tapestry5.ioc.services.ApplicationDefaults;
|
||||
import org.apache.tapestry5.ioc.services.SymbolProvider;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
/**
|
||||
* This module is automatically included as part of the Tapestry IoC Registry, it's a good place to
|
||||
* configure and extend Tapestry, or to place your own service definitions.
|
||||
*/
|
||||
public class AppModule {
|
||||
public static void bind(ServiceBinder binder) {
|
||||
// binder.bind(MyServiceInterface.class, MyServiceImpl.class);
|
||||
|
||||
// Make bind() calls on the binder object to define most IoC services.
|
||||
// Use service builder methods (example below) when the implementation
|
||||
// is provided inline, or requires more initialization than simply
|
||||
// invoking the constructor.
|
||||
}
|
||||
|
||||
public static void contributeFactoryDefaults(
|
||||
MappedConfiguration<String, Object> configuration) {
|
||||
// The values defined here (as factory default overrides) are themselves
|
||||
// overridden with application defaults by DevelopmentModule and QaModule.
|
||||
|
||||
// The application version is primarily useful as it appears in
|
||||
// any exception reports (HTML or textual).
|
||||
configuration.override(SymbolConstants.APPLICATION_VERSION, "0.0.1-SNAPSHOT");
|
||||
|
||||
// This is something that should be removed when going to production, but is useful
|
||||
// in the early stages of development.
|
||||
configuration.override(SymbolConstants.PRODUCTION_MODE, false);
|
||||
}
|
||||
|
||||
public static void contributeApplicationDefaults(
|
||||
MappedConfiguration<String, Object> configuration) {
|
||||
// Contributions to ApplicationDefaults will override any contributions to
|
||||
// FactoryDefaults (with the same key). Here we're restricting the supported
|
||||
// locales to just "en" (English). As you add localised message catalogs and other assets,
|
||||
// you can extend this list of locales (it's a comma separated series of locale names;
|
||||
// the first locale name is the default when there's no reasonable match).
|
||||
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
|
||||
|
||||
// You should change the passphrase immediately; the HMAC passphrase is used to secure
|
||||
// the hidden field data stored in forms to encrypt and digitally sign client-side data.
|
||||
configuration.add(SymbolConstants.HMAC_PASSPHRASE, "change this immediately");
|
||||
}
|
||||
|
||||
/**
|
||||
* Use annotation or method naming convention: <code>contributeApplicationDefaults</code>
|
||||
*/
|
||||
@Contribute(SymbolProvider.class)
|
||||
@ApplicationDefaults
|
||||
public static void setupEnvironment(MappedConfiguration<String, Object> configuration) {
|
||||
// Support for jQuery is new in Tapestry 5.4 and will become the only supported
|
||||
// option in 5.5.
|
||||
configuration.add(SymbolConstants.JAVASCRIPT_INFRASTRUCTURE_PROVIDER, "jquery");
|
||||
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "context:mybootstrap");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a service definition, the service will be named "TimingFilter". The interface,
|
||||
* RequestFilter, is used within the RequestHandler service pipeline, which is built from the
|
||||
* RequestHandler service configuration. Tapestry IoC is responsible for passing in an
|
||||
* appropriate Logger instance. Requests for static resources are handled at a higher level, so
|
||||
* this filter will only be invoked for Tapestry related requests.
|
||||
*
|
||||
*
|
||||
* Service builder methods are useful when the implementation is inline as an inner class
|
||||
* (as here) or require some other kind of special initialization. In most cases,
|
||||
* use the static bind() method instead.
|
||||
*
|
||||
*
|
||||
* If this method was named "build", then the service id would be taken from the
|
||||
* service interface and would be "RequestFilter". Since Tapestry already defines
|
||||
* a service named "RequestFilter" we use an explicit service id that we can reference
|
||||
* inside the contribution method.
|
||||
*/
|
||||
public RequestFilter buildTimingFilter(final Logger log) {
|
||||
return new RequestFilter() {
|
||||
public boolean service(Request request, Response response, RequestHandler handler)
|
||||
throws IOException {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
// The responsibility of a filter is to invoke the corresponding method
|
||||
// in the handler. When you chain multiple filters together, each filter
|
||||
// received a handler that is a bridge to the next filter.
|
||||
|
||||
return handler.service(request, response);
|
||||
} finally {
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
|
||||
log.info("Request time: {} ms", elapsed);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a contribution to the RequestHandler service configuration. This is how we extend
|
||||
* Tapestry using the timing filter. A common use for this kind of filter is transaction
|
||||
* management or security. The @Local annotation selects the desired service by type, but only
|
||||
* from the same module. Without @Local, there would be an error due to the other service(s)
|
||||
* that implement RequestFilter (defined in other modules).
|
||||
*/
|
||||
@Contribute(RequestHandler.class)
|
||||
public void addTimingFilter(OrderedConfiguration<RequestFilter> configuration, @Local RequestFilter filter) {
|
||||
// Each contribution to an ordered configuration has a name, When necessary, you may
|
||||
// set constraints to precisely control the invocation order of the contributed filter
|
||||
// within the pipeline.
|
||||
|
||||
configuration.add("Timing", filter);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.tapestry.services;
|
||||
|
||||
import org.apache.tapestry5.SymbolConstants;
|
||||
import org.apache.tapestry5.commons.MappedConfiguration;
|
||||
|
||||
/**
|
||||
* This module is automatically included as part of the Tapestry IoC Registry if <em>tapestry.execution-mode</em>
|
||||
* includes <code>development</code>.
|
||||
*/
|
||||
public class DevelopmentModule {
|
||||
public static void contributeApplicationDefaults(
|
||||
MappedConfiguration<String, Object> configuration) {
|
||||
// The factory default is true but during the early stages of an application
|
||||
// overriding to false is a good idea. In addition, this is often overridden
|
||||
// on the command line as -Dtapestry.production-mode=false
|
||||
configuration.add(SymbolConstants.PRODUCTION_MODE, false);
|
||||
|
||||
// The application version number is incorprated into URLs for some
|
||||
// assets. Web browsers will cache assets because of the far future expires
|
||||
// header. If existing assets are changed, the version number should also
|
||||
// change, to force the browser to download new versions.
|
||||
configuration.add(SymbolConstants.APPLICATION_VERSION, "0.0.1-SNAPSHOT-DEV");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.tapestry.services;
|
||||
|
||||
import org.apache.tapestry5.SymbolConstants;
|
||||
import org.apache.tapestry5.commons.MappedConfiguration;
|
||||
import org.apache.tapestry5.ioc.ServiceBinder;
|
||||
|
||||
/**
|
||||
* This module is automatically included as part of the Tapestry IoC Registry if <em>tapestry.execution-mode</em>
|
||||
* includes <code>qa</code> ("quality assurance").
|
||||
*/
|
||||
public class QaModule
|
||||
{
|
||||
public static void bind(ServiceBinder binder)
|
||||
{
|
||||
// Bind any services needed by the QA team to produce their reports
|
||||
// binder.bind(MyServiceMonitorInterface.class, MyServiceMonitorImpl.class);
|
||||
}
|
||||
|
||||
|
||||
public static void contributeApplicationDefaults(
|
||||
MappedConfiguration<String, Object> configuration)
|
||||
{
|
||||
// The factory default is true but during the early stages of an application
|
||||
// overriding to false is a good idea. In addition, this is often overridden
|
||||
// on the command line as -Dtapestry.production-mode=false
|
||||
configuration.add(SymbolConstants.PRODUCTION_MODE, false);
|
||||
|
||||
// The application version number is incorprated into URLs for some
|
||||
// assets. Web browsers will cache assets because of the far future expires
|
||||
// header. If existing assets are changed, the version number should also
|
||||
// change, to force the browser to download new versions.
|
||||
configuration.add(SymbolConstants.APPLICATION_VERSION, "0.0.1-SNAPSHOT-QA");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
|
||||
<head>
|
||||
<title>${title}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<t:alerts/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<t:body />
|
||||
<hr />
|
||||
<footer>
|
||||
<p>© Your Company</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="com.baeldung.tapestry" level="TRACE"/>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,11 @@
|
|||
<html t:type="layout" title="Not found apache-tapestry"
|
||||
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
|
||||
xmlns:p="tapestry:parameter">
|
||||
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<h1>Requested page not found!</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
introMsg=Welcome to the Apache Tapestry Tutorial
|
|
@ -0,0 +1,14 @@
|
|||
<html t:type="layout" title="apache-tapestry Home" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
|
||||
|
||||
<h1>Home! ${appName}</h1>
|
||||
<h2>${message:introMsg}</h2>
|
||||
<h3>${currentTime}</h3>
|
||||
<p><t:eventlink event="callAjax" zone="ajaxZone" class="btn btn-default">Call Ajax</t:eventlink></p>
|
||||
<t:zone t:id="ajaxZone" class="span4"></t:zone>
|
||||
<t:block t:id="ajaxBlock">
|
||||
<hr/>
|
||||
<h2>Rendered through Ajax</h2>
|
||||
<p>The current time is: <strong>${currentTime}</strong></p>
|
||||
</t:block>
|
||||
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
greeting=Welcome to Tapestry 5! We hope that this project template will get you going in style.
|
|
@ -0,0 +1,46 @@
|
|||
<html t:type="layout" title="apache-tapestry Index"
|
||||
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
|
||||
>
|
||||
|
||||
<!-- Most of the page content, including <head>, <body>, etc. tags, comes from Layout.tml -->
|
||||
|
||||
<!-- Main hero unit for a primary marketing message or call to action -->
|
||||
<div class="hero-unit">
|
||||
<p>
|
||||
<img src="${asset:context:images/tapestry.png}"
|
||||
alt="${message:greeting}" title="${message:greeting}"/>
|
||||
</p>
|
||||
<h3>${message:greeting}</h3>
|
||||
<p>The current time is: <strong>${currentTime}</strong></p>
|
||||
<p>
|
||||
This is a template for a simple marketing or informational website. It includes a large callout called
|
||||
the hero unit and three supporting pieces of content. Use it as a starting point to create something
|
||||
more unique.
|
||||
</p>
|
||||
<p><t:actionlink t:id="learnmore" class="btn btn-primary btn-large">Learn more »</t:actionlink></p>
|
||||
</div>
|
||||
|
||||
<!-- Example row of columns -->
|
||||
<div class="row">
|
||||
<div class="span4">
|
||||
<h2>Normal link</h2>
|
||||
<p>Clink the bottom link and the page refresh with event <code>complete</code></p>
|
||||
<p><t:eventlink event="complete" class="btn btn-default">Complete»</t:eventlink></p>
|
||||
</div>
|
||||
<t:zone t:id="middlezone" class="span4">
|
||||
|
||||
</t:zone>
|
||||
<div class="span4">
|
||||
<h2>Ajax link</h2>
|
||||
<p>Click the bottom link to update just the middle column with Ajax call with event <code>ajax</code></p>
|
||||
<p><t:eventlink event="ajax" zone="middlezone" class="btn btn-default">Ajax»</t:eventlink></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<t:block t:id="block">
|
||||
<h2>Ajax updated</h2>
|
||||
<p>I'v been updated through AJAX call</p>
|
||||
<p>The current time is: <strong>${currentTime}</strong></p>
|
||||
</t:block>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<html t:type="layout" title="apache-tapestry com.example"
|
||||
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
|
||||
xmlns:p="tapestry:parameter">
|
||||
|
||||
<div class="row">
|
||||
<div class="span4 offset3">
|
||||
<t:form t:id="login">
|
||||
<h2>Please sign in</h2>
|
||||
<t:textfield t:id="email" class="input-block-level" placeholder="Email address"/>
|
||||
<t:passwordfield t:id="password" class="input-block-level" placeholder="Password"/>
|
||||
<t:submit class="btn btn-large btn-primary" value="Sign in"/>
|
||||
</t:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,44 @@
|
|||
# Default to info level output; this is very handy if you eventually use Hibernate as well.
|
||||
log4j.rootCategory=info, A1
|
||||
|
||||
# A1 is set to be a ConsoleAppender.
|
||||
log4j.appender.A1=org.apache.log4j.ConsoleAppender
|
||||
|
||||
# A1 uses PatternLayout.
|
||||
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.A1.layout.ConversionPattern=[%p] %c{2} %m%n
|
||||
|
||||
# Service category names are the name of the defining module class
|
||||
# and then the service id.
|
||||
log4j.category.com.baeldung.tapestry.services.AppModule.TimingFilter=info
|
||||
|
||||
# Outputs a list of pages, components and mixins at startup.
|
||||
log4j.category.org.apache.tapestry5.modules.TapestryModule.ComponentClassResolver=info
|
||||
|
||||
# Outputs startup statistics; elapsed time to setup and initialize the registry, a list of
|
||||
# available services, and a launch banner that includes the Tapestry version number.
|
||||
log4j.category.org.apache.tapestry5.TapestryFilter=info
|
||||
|
||||
|
||||
# Turning on debug mode for a page's or component's transformer logger
|
||||
# will show all of the code changes that occur when the
|
||||
# class is loaded.
|
||||
|
||||
# log4j.category.tapestry.transformer.com.baeldung.tapestry.pages.Index=debug
|
||||
|
||||
# Turning on debug mode for a component's events logger will show all the events triggered on the
|
||||
# component, and which component methods are invoked as a result.
|
||||
|
||||
# log4j.category.tapestry.events.com.baeldung.tapestry.pages.Index=debug
|
||||
|
||||
# Turning on trace mode for a page's render logger provides extended information about every step
|
||||
# in rendering (this is not generally helpful). Turning on debug mode will add a one-line
|
||||
# summary that includes the elapsed render time, which can be useful in tracking down
|
||||
# performance issues.
|
||||
|
||||
# log4j.category.tapestry.render.com.baeldung.tapestry.pages.Index=debug
|
||||
|
||||
# Turn on some verbose debugging about everything in the application. This is nice initially,
|
||||
# while getting everything set up. You'll probably want to remove this once you are
|
||||
# up and running, replacing it with more selective debugging output.
|
||||
log4j.category.com.baeldung.tapestry=debug
|
|
@ -0,0 +1,4 @@
|
|||
# This is where global application properties go.
|
||||
# You can also have individual message catalogs for each page and each
|
||||
# component that override these defaults.
|
||||
# The name of this file is based on the <filter-name> element in web.
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
|
||||
<display-name>apache-tapestry Tapestry 5 Application</display-name>
|
||||
<context-param>
|
||||
<!--
|
||||
The only significant configuration for Tapestry 5, this informs Tapestry
|
||||
of where to look for pages, components and mixins.
|
||||
-->
|
||||
<param-name>tapestry.app-package</param-name>
|
||||
<param-value>com.baeldung.tapestry</param-value>
|
||||
</context-param>
|
||||
|
||||
<!--
|
||||
Specify some additional Modules for two different execution
|
||||
modes: development and qa.
|
||||
Remember that the default execution mode is production
|
||||
-->
|
||||
<context-param>
|
||||
<param-name>tapestry.development-modules</param-name>
|
||||
<param-value>
|
||||
com.baeldung.tapestry.services.DevelopmentModule
|
||||
</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>tapestry.qa-modules</param-name>
|
||||
<param-value>
|
||||
com.baeldung.tapestry.services.QaModule
|
||||
</param-value>
|
||||
</context-param>
|
||||
|
||||
|
||||
<!-- Filter configuration -->
|
||||
<filter>
|
||||
<filter-name>app</filter-name>
|
||||
<filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>app</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
<dispatcher>REQUEST</dispatcher>
|
||||
<dispatcher>ERROR</dispatcher>
|
||||
</filter-mapping>
|
||||
|
||||
<error-page>
|
||||
<error-code>404</error-code>
|
||||
<location>/error404</location>
|
||||
</error-page>
|
||||
|
||||
</web-app>
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,116 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: button.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#buttons
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// BUTTON PUBLIC CLASS DEFINITION
|
||||
// ==============================
|
||||
|
||||
var Button = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, Button.DEFAULTS, options)
|
||||
this.isLoading = false
|
||||
}
|
||||
|
||||
Button.VERSION = '3.3.4'
|
||||
|
||||
Button.DEFAULTS = {
|
||||
loadingText: 'loading...'
|
||||
}
|
||||
|
||||
Button.prototype.setState = function (state) {
|
||||
var d = 'disabled'
|
||||
var $el = this.$element
|
||||
var val = $el.is('input') ? 'val' : 'html'
|
||||
var data = $el.data()
|
||||
|
||||
state = state + 'Text'
|
||||
|
||||
if (data.resetText == null) $el.data('resetText', $el[val]())
|
||||
|
||||
// push to event loop to allow forms to submit
|
||||
setTimeout($.proxy(function () {
|
||||
$el[val](data[state] == null ? this.options[state] : data[state])
|
||||
|
||||
if (state == 'loadingText') {
|
||||
this.isLoading = true
|
||||
$el.addClass(d).attr(d, d)
|
||||
} else if (this.isLoading) {
|
||||
this.isLoading = false
|
||||
$el.removeClass(d).removeAttr(d)
|
||||
}
|
||||
}, this), 0)
|
||||
}
|
||||
|
||||
Button.prototype.toggle = function () {
|
||||
var changed = true
|
||||
var $parent = this.$element.closest('[data-toggle="buttons"]')
|
||||
|
||||
if ($parent.length) {
|
||||
var $input = this.$element.find('input')
|
||||
if ($input.prop('type') == 'radio') {
|
||||
if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
|
||||
else $parent.find('.active').removeClass('active')
|
||||
}
|
||||
if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
|
||||
} else {
|
||||
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
|
||||
}
|
||||
|
||||
if (changed) this.$element.toggleClass('active')
|
||||
}
|
||||
|
||||
|
||||
// BUTTON PLUGIN DEFINITION
|
||||
// ========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.button')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.button', (data = new Button(this, options)))
|
||||
|
||||
if (option == 'toggle') data.toggle()
|
||||
else if (option) data.setState(option)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.button
|
||||
|
||||
$.fn.button = Plugin
|
||||
$.fn.button.Constructor = Button
|
||||
|
||||
|
||||
// BUTTON NO CONFLICT
|
||||
// ==================
|
||||
|
||||
$.fn.button.noConflict = function () {
|
||||
$.fn.button = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// BUTTON DATA-API
|
||||
// ===============
|
||||
|
||||
$(document)
|
||||
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||||
var $btn = $(e.target)
|
||||
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
|
||||
Plugin.call($btn, 'toggle')
|
||||
e.preventDefault()
|
||||
})
|
||||
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||||
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
|
||||
})
|
||||
|
||||
}(jQuery);
|
|
@ -0,0 +1,9 @@
|
|||
----
|
||||
Module com.baeldung:apache-tapestry
|
||||
----
|
||||
|
||||
com.baeldung:apache-tapestry Documentation
|
||||
|
||||
This is where you can start to document your module.
|
||||
|
||||
Create new files in the Maven APT format, and update the site.xml file to point to them.
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<project name="Generated site for apache-tapestry">
|
||||
|
||||
<publishDate format="dd MMM yyyy"/>
|
||||
|
||||
<version/>
|
||||
|
||||
<body>
|
||||
|
||||
<menu name="apache-tapestry Project">
|
||||
<item name="About" href="index.html"/>
|
||||
</menu>
|
||||
|
||||
<menu ref="reports"/>
|
||||
|
||||
</body>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
|
||||
<suite name="apache-tapestry Application Test Suite" annotations="1.5">
|
||||
<test name="Unit Tests">
|
||||
<packages>
|
||||
<package name="com.baeldung.tapestry"/>
|
||||
</packages>
|
||||
</test>
|
||||
</suite>
|
|
@ -0,0 +1,278 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<web-app
|
||||
xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
|
||||
<description>
|
||||
Default web.xml file.
|
||||
This file is applied to a Web application before it's own WEB_INF/web.xml file
|
||||
</description>
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- Context params to control Session Cookies -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<context-param>
|
||||
<param-name>org.mortbay.jetty.servlet.SessionDomain</param-name>
|
||||
<param-value>127.0.0.1</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>org.mortbay.jetty.servlet.SessionPath</param-name>
|
||||
<param-value>/</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>org.mortbay.jetty.servlet.MaxAge</param-name>
|
||||
<param-value>-1</param-value>
|
||||
</context-param>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- The default servlet. -->
|
||||
<!-- This servlet, normally mapped to /, provides the handling for static -->
|
||||
<!-- content, OPTIONS and TRACE methods for the context. -->
|
||||
<!-- The following initParameters are supported: -->
|
||||
<!-- -->
|
||||
<!-- acceptRanges If true, range requests and responses are -->
|
||||
<!-- supported -->
|
||||
<!-- -->
|
||||
<!-- dirAllowed If true, directory listings are returned if no -->
|
||||
<!-- welcome file is found. Else 403 Forbidden. -->
|
||||
<!-- -->
|
||||
<!-- putAllowed If true, the PUT method is allowed -->
|
||||
<!-- -->
|
||||
<!-- delAllowed If true, the DELETE method is allowed -->
|
||||
<!-- -->
|
||||
<!-- redirectWelcome If true, redirect welcome file requests -->
|
||||
<!-- else use request dispatcher forwards -->
|
||||
<!-- -->
|
||||
<!-- minGzipLength If set to a positive integer, then static content -->
|
||||
<!-- larger than this will be served as gzip content -->
|
||||
<!-- encoded if a matching resource is found ending -->
|
||||
<!-- with ".gz" -->
|
||||
<!-- -->
|
||||
<!-- resoureBase Can be set to replace the context resource base -->
|
||||
<!-- -->
|
||||
<!-- relativeResourceBase -->
|
||||
<!-- Set with a pathname relative to the base of the -->
|
||||
<!-- servlet context root. Useful for only serving -->
|
||||
<!-- static content from only specific subdirectories. -->
|
||||
<!-- -->
|
||||
<!-- The MOVE method is allowed if PUT and DELETE are allowed -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<servlet>
|
||||
<servlet-name>default</servlet-name>
|
||||
<servlet-class>org.mortbay.jetty.servlet.Default</servlet-class>
|
||||
<init-param>
|
||||
<param-name>acceptRanges</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>dirAllowed</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>putAllowed</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>delAllowed</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>redirectWelcome</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>minGzipLength</param-name>
|
||||
<param-value>8192</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>0</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>default</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<session-config>
|
||||
<session-timeout>30</session-timeout>
|
||||
</session-config>
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
<welcome-file>index.htm</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<locale-encoding-mapping-list>
|
||||
<locale-encoding-mapping>
|
||||
<locale>ar</locale>
|
||||
<encoding>ISO-8859-6</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>be</locale>
|
||||
<encoding>ISO-8859-5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>bg</locale>
|
||||
<encoding>ISO-8859-5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>ca</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>cs</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>da</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>de</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>el</locale>
|
||||
<encoding>ISO-8859-7</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>en</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>es</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>et</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>fi</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>fr</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>hr</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>hu</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>is</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>it</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>iw</locale>
|
||||
<encoding>ISO-8859-8</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>ja</locale>
|
||||
<encoding>Shift_JIS</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>ko</locale>
|
||||
<encoding>EUC-KR</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>lt</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>lv</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>mk</locale>
|
||||
<encoding>ISO-8859-5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>nl</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>no</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>pl</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>pt</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>ro</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>ru</locale>
|
||||
<encoding>ISO-8859-5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>sh</locale>
|
||||
<encoding>ISO-8859-5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>sk</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>sl</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>sq</locale>
|
||||
<encoding>ISO-8859-2</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>sr</locale>
|
||||
<encoding>ISO-8859-5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>sv</locale>
|
||||
<encoding>ISO-8859-1</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>tr</locale>
|
||||
<encoding>ISO-8859-9</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>uk</locale>
|
||||
<encoding>ISO-8859-5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>zh</locale>
|
||||
<encoding>GB2312</encoding>
|
||||
</locale-encoding-mapping>
|
||||
<locale-encoding-mapping>
|
||||
<locale>zh_TW</locale>
|
||||
<encoding>Big5</encoding>
|
||||
</locale-encoding-mapping>
|
||||
</locale-encoding-mapping-list>
|
||||
|
||||
|
||||
</web-app>
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>blade</artifactId>
|
||||
<name>blade</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.bladejava</groupId>
|
||||
<artifactId>blade-mvc</artifactId>
|
||||
<version>${blade-mvc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>bootstrap</artifactId>
|
||||
<version>${bootstrap.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<!-- PROVIDED -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- TEST -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${httpclient.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
<version>${httpmime.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>${httpcore.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>blade</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<configuration>
|
||||
<skipITs>true</skipITs>
|
||||
<includes>
|
||||
<include>**/*LiveTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>${assembly.plugin.version}</version>
|
||||
<configuration>
|
||||
<finalName>${project.build.finalName}</finalName>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.baeldung.blade.sample.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<blade-mvc.version>2.0.14.RELEASE</blade-mvc.version>
|
||||
<bootstrap.version>4.2.1</bootstrap.version>
|
||||
<httpclient.version>4.5.6</httpclient.version>
|
||||
<httpmime.version>4.5.6</httpmime.version>
|
||||
<httpcore.version>4.4.10</httpcore.version>
|
||||
<process-exec-maven-plugin.version>0.7</process-exec-maven-plugin.version>
|
||||
<assembly.plugin.version>3.1.0</assembly.plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.bootique</groupId>
|
||||
<artifactId>bootique</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>bootique</name>
|
||||
<packaging>jar</packaging>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.bootique.bom</groupId>
|
||||
<artifactId>bootique-bom</artifactId>
|
||||
<version>${bootique-bom.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.bootique.jersey</groupId>
|
||||
<artifactId>bootique-jersey</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.bootique.logback</groupId>
|
||||
<artifactId>bootique-logback</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.bootique</groupId>
|
||||
<artifactId>bootique-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>${maven-shade-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>
|
||||
--add-opens java.base/java.lang=ALL-UNNAMED
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<main.class>com.baeldung.bootique.App</main.class>
|
||||
<bootique-bom.version>0.23</bootique-bom.version>
|
||||
<maven-shade-plugin.version>2.4.3</maven-shade-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,5 @@
|
|||
# Dropwizard
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Introduction to Dropwizard](https://www.baeldung.com/java-dropwizard)
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>dropwizard</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>dropwizard</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard</groupId>
|
||||
<artifactId>dropwizard-core</artifactId>
|
||||
<version>${dropwizard.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>com.baeldung.dropwizard.introduction.IntroductionApplication</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<dropwizard.version>2.0.0</dropwizard.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.dropwizard.introduction;
|
||||
|
||||
import com.baeldung.dropwizard.introduction.configuration.ApplicationHealthCheck;
|
||||
import com.baeldung.dropwizard.introduction.configuration.BasicConfiguration;
|
||||
import com.baeldung.dropwizard.introduction.domain.Brand;
|
||||
import com.baeldung.dropwizard.introduction.repository.BrandRepository;
|
||||
import com.baeldung.dropwizard.introduction.resource.BrandResource;
|
||||
import io.dropwizard.Application;
|
||||
import io.dropwizard.configuration.ResourceConfigurationSourceProvider;
|
||||
import io.dropwizard.setup.Bootstrap;
|
||||
import io.dropwizard.setup.Environment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IntroductionApplication extends Application<BasicConfiguration> {
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
new IntroductionApplication().run("server", "introduction-config.yml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final BasicConfiguration basicConfiguration, final Environment environment) {
|
||||
final int defaultSize = basicConfiguration.getDefaultSize();
|
||||
final BrandRepository brandRepository = new BrandRepository(initBrands());
|
||||
final BrandResource brandResource = new BrandResource(defaultSize, brandRepository);
|
||||
environment
|
||||
.jersey()
|
||||
.register(brandResource);
|
||||
|
||||
final ApplicationHealthCheck healthCheck = new ApplicationHealthCheck();
|
||||
environment
|
||||
.healthChecks()
|
||||
.register("application", healthCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final Bootstrap<BasicConfiguration> bootstrap) {
|
||||
bootstrap.setConfigurationSourceProvider(new ResourceConfigurationSourceProvider());
|
||||
super.initialize(bootstrap);
|
||||
}
|
||||
|
||||
private List<Brand> initBrands() {
|
||||
final List<Brand> brands = new ArrayList<>();
|
||||
brands.add(new Brand(1L, "Brand1"));
|
||||
brands.add(new Brand(2L, "Brand2"));
|
||||
brands.add(new Brand(3L, "Brand3"));
|
||||
|
||||
return brands;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.baeldung.dropwizard.introduction.configuration;
|
||||
|
||||
import com.codahale.metrics.health.HealthCheck;
|
||||
|
||||
public class ApplicationHealthCheck extends HealthCheck {
|
||||
@Override
|
||||
protected Result check() throws Exception {
|
||||
return Result.healthy();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.dropwizard.introduction.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.dropwizard.Configuration;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class BasicConfiguration extends Configuration {
|
||||
@NotNull private final int defaultSize;
|
||||
|
||||
@JsonCreator
|
||||
public BasicConfiguration(@JsonProperty("defaultSize") final int defaultSize) {
|
||||
this.defaultSize = defaultSize;
|
||||
}
|
||||
|
||||
public int getDefaultSize() {
|
||||
return defaultSize;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.dropwizard.introduction.domain;
|
||||
|
||||
public class Brand {
|
||||
private final Long id;
|
||||
private final String name;
|
||||
|
||||
public Brand(final Long id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.dropwizard.introduction.repository;
|
||||
|
||||
import com.baeldung.dropwizard.introduction.domain.Brand;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BrandRepository {
|
||||
private final List<Brand> brands;
|
||||
|
||||
public BrandRepository(final List<Brand> brands) {
|
||||
this.brands = ImmutableList.copyOf(brands);
|
||||
}
|
||||
|
||||
public List<Brand> findAll(final int size) {
|
||||
return brands
|
||||
.stream()
|
||||
.limit(size)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Optional<Brand> findById(final Long id) {
|
||||
return brands
|
||||
.stream()
|
||||
.filter(brand -> brand
|
||||
.getId()
|
||||
.equals(id))
|
||||
.findFirst();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.dropwizard.introduction.resource;
|
||||
|
||||
import com.baeldung.dropwizard.introduction.domain.Brand;
|
||||
import com.baeldung.dropwizard.introduction.repository.BrandRepository;
|
||||
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Path("/brands")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public class BrandResource {
|
||||
private final int defaultSize;
|
||||
private final BrandRepository brandRepository;
|
||||
|
||||
public BrandResource(final int defaultSize, final BrandRepository brandRepository) {
|
||||
this.defaultSize = defaultSize;
|
||||
this.brandRepository = brandRepository;
|
||||
|
||||
}
|
||||
|
||||
@GET
|
||||
public List<Brand> getBrands(@QueryParam("size") final Optional<Integer> size) {
|
||||
return brandRepository.findAll(size.orElse(defaultSize));
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Brand getById(@PathParam("id") final Long id) {
|
||||
return brandRepository
|
||||
.findById(id)
|
||||
.orElseThrow(RuntimeException::new);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
defaultSize: 5
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.dropwizard.introduction.repository;
|
||||
|
||||
import com.baeldung.dropwizard.introduction.domain.Brand;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class BrandRepositoryUnitTest {
|
||||
|
||||
private static final Brand BRAND_1 = new Brand(1L, "Brand1");
|
||||
|
||||
private final BrandRepository brandRepository = new BrandRepository(getBrands());
|
||||
|
||||
@Test
|
||||
void givenSize_whenFindingAll_thenReturnList() {
|
||||
final int size = 2;
|
||||
|
||||
final List<Brand> result = brandRepository.findAll(size);
|
||||
|
||||
assertEquals(size, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenId_whenFindingById_thenReturnFoundBrand() {
|
||||
final Long id = BRAND_1.getId();
|
||||
|
||||
final Optional<Brand> result = brandRepository.findById(id);
|
||||
|
||||
Assertions.assertTrue(result.isPresent());
|
||||
assertEquals(BRAND_1, result.get());
|
||||
}
|
||||
|
||||
|
||||
private List<Brand> getBrands() {
|
||||
final List<Brand> brands = new ArrayList<>();
|
||||
brands.add(BRAND_1);
|
||||
brands.add(new Brand(2L, "Brand2"));
|
||||
brands.add(new Brand(3L, "Brand3"));
|
||||
|
||||
return brands;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<!-- POM file generated with GWT webAppCreator -->
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>google-web-toolkit</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>google-web-toolkit</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- ensure all GWT deps use the same version (unless overridden) -->
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt</artifactId>
|
||||
<version>${gwt.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-servlet</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-user</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.gwt</groupId>
|
||||
<artifactId>gwt-dev</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- Output classes directly into the webapp, -->
|
||||
<!-- so that IDEs and "mvn process-classes" update them in DevMode -->
|
||||
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
|
||||
<plugins>
|
||||
<!-- GWT Maven Plugin -->
|
||||
<plugin>
|
||||
<groupId>net.ltgt.gwt.maven</groupId>
|
||||
<artifactId>gwt-maven-plugin</artifactId>
|
||||
<version>${gwt.plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<moduleName>com.baeldung.Google_web_toolkit</moduleName>
|
||||
<moduleShortName>Google_web_toolkit</moduleShortName>
|
||||
<failOnError>true</failOnError>
|
||||
<!-- GWT compiler 2.8 requires 1.8, hence define sourceLevel here -->
|
||||
<!--if you use a different source language for java compilation -->
|
||||
<sourceLevel>${maven.compiler.source}</sourceLevel>
|
||||
<!-- Compiler configuration -->
|
||||
<compilerArgs>
|
||||
<!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
|
||||
<arg>-compileReport</arg>
|
||||
<arg>-XcompilerMetrics</arg>
|
||||
</compilerArgs>
|
||||
<!-- DevMode configuration -->
|
||||
<warDir>${project.build.directory}/${project.build.finalName}</warDir>
|
||||
<classpathScope>compile+runtime</classpathScope>
|
||||
<!-- URL(s) that should be opened by DevMode (gwt:devmode). -->
|
||||
<startupUrls>
|
||||
<startupUrl>Google_web_toolkit.html</startupUrl>
|
||||
</startupUrls>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Skip normal test execution, we use gwt:test instead -->
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<!-- Setting maven.compiler.source to something different to 1.8 needs that you configure the -->
|
||||
<!-- sourceLevel in gwt-maven-plugin since GWT compiler 2.8 requires 1.8 -->
|
||||
<!--(see gwt-maven-plugin block below) -->
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<gwt.version>2.8.2</gwt.version>
|
||||
<gwt.plugin.version>1.0-rc-8</gwt.plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Introduction to Jakarta EE MVC / Eclipse Krazo](https://www.baeldung.com/java-ee-mvc-eclipse-krazo)
|
|
@ -0,0 +1,109 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>jakarta-ee</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>jakarta-ee</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.platform</groupId>
|
||||
<artifactId>jakarta.jakartaee-web-api</artifactId>
|
||||
<version>${jakartaee-api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.mvc</groupId>
|
||||
<artifactId>jakarta.mvc-api</artifactId>
|
||||
<version>${jakarta.mvc-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.krazo</groupId>
|
||||
<artifactId>krazo-jersey</artifactId>
|
||||
<version>${krazo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>mvc-2.0</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.glassfish.maven.plugin</groupId>
|
||||
<artifactId>maven-glassfish-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<glassfishDirectory>${local.glassfish.home}</glassfishDirectory>
|
||||
<user>admin</user>
|
||||
<!-- <passwordFile>${local.glassfish.passfile}</passwordFile> -->
|
||||
<adminPassword>password</adminPassword>
|
||||
<domain>
|
||||
<name>${local.glassfish.domain}</name>
|
||||
<httpPort>8080</httpPort>
|
||||
<adminPort>4848</adminPort>
|
||||
</domain>
|
||||
<components>
|
||||
<component>
|
||||
<name>${project.artifactId}</name>
|
||||
<artifact>target/${project.build.finalName}.war</artifact>
|
||||
</component>
|
||||
</components>
|
||||
<debug>true</debug>
|
||||
<terse>false</terse>
|
||||
<echo>true</echo>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jakartaee-api.version>9.0.0</jakartaee-api.version>
|
||||
<krazo.version>2.0.0</krazo.version>
|
||||
<jakarta.mvc-api.version>2.0.0</jakarta.mvc-api.version>
|
||||
<junit.jupiter.version>5.8.2</junit.jupiter.version>
|
||||
<local.glassfish.home>C:/glassfish6</local.glassfish.home>
|
||||
<local.glassfish.user>admin</local.glassfish.user>
|
||||
<local.glassfish.domain>mvn-domain</local.glassfish.domain>
|
||||
<mockito.version>1.10.19</mockito.version>
|
||||
<local.glassfish.passfile>
|
||||
${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords
|
||||
</local.glassfish.passfile>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,84 @@
|
|||
package com.baeldung.eclipse.krazo;
|
||||
|
||||
import jakarta.enterprise.context.RequestScoped;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.mvc.RedirectScoped;
|
||||
import jakarta.mvc.binding.MvcBinding;
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import jakarta.ws.rs.FormParam;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Named("user")
|
||||
@RedirectScoped
|
||||
public class User implements Serializable {
|
||||
@MvcBinding
|
||||
@Null
|
||||
private String id;
|
||||
|
||||
@MvcBinding
|
||||
@NotNull
|
||||
@Size(min = 1, message = "Name cannot be blank")
|
||||
@FormParam("name")
|
||||
private String name;
|
||||
|
||||
@MvcBinding
|
||||
@Min(value = 18, message = "The minimum age of the user should be 18 years")
|
||||
@FormParam("age")
|
||||
private int age;
|
||||
|
||||
@MvcBinding
|
||||
@Email(message = "The email cannot be blank and should be in a valid format")
|
||||
@Size(min=3, message = "Email cannot be empty")
|
||||
@FormParam("email")
|
||||
private String email;
|
||||
|
||||
@MvcBinding
|
||||
@Null
|
||||
@FormParam("phone")
|
||||
private String phone;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.eclipse.krazo;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.core.Application;
|
||||
|
||||
/**
|
||||
* Default JAX-RS application listening on /app
|
||||
*/
|
||||
@ApplicationPath("/app")
|
||||
public class UserApplication extends Application {
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.eclipse.krazo;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.mvc.Controller;
|
||||
import jakarta.mvc.Models;
|
||||
import jakarta.mvc.binding.BindingResult;
|
||||
import jakarta.mvc.security.CsrfProtected;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.BeanParam;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The class contains two controllers and a REST API
|
||||
*/
|
||||
@Path("users")
|
||||
public class UserController {
|
||||
@Inject
|
||||
private BindingResult bindingResult;
|
||||
|
||||
private static final List<User> users = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
private Models models;
|
||||
|
||||
/**
|
||||
* This is a controller. It displays a initial form to the user.
|
||||
* @return The view name
|
||||
*/
|
||||
@GET
|
||||
@Controller
|
||||
public String showForm() {
|
||||
return "user.jsp";
|
||||
}
|
||||
|
||||
/**
|
||||
* The method handles the form submits
|
||||
* Handles HTTP POST and is CSRF protected. The client invoking this controller should provide a CSRF token.
|
||||
* @param user The user details that has to be stored
|
||||
* @return Returns a view name
|
||||
*/
|
||||
@POST
|
||||
@Controller
|
||||
@CsrfProtected
|
||||
public String saveUser(@Valid @BeanParam User user) {
|
||||
if (bindingResult.isFailed()) {
|
||||
models.put("errors", bindingResult.getAllErrors());
|
||||
return "user.jsp";
|
||||
}
|
||||
String id = UUID.randomUUID().toString();
|
||||
user.setId(id);
|
||||
users.add(user);
|
||||
return "redirect:users/success";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a redirect view
|
||||
* @return The view name
|
||||
*/
|
||||
@GET
|
||||
@Controller
|
||||
@Path("success")
|
||||
public String saveUserSuccess() {
|
||||
return "success.jsp";
|
||||
}
|
||||
|
||||
/**
|
||||
* The REST API that returns all the user details in the JSON format
|
||||
* @return The list of users that are saved. The List<User> is converted into Json Array.
|
||||
* If no user is present a empty array is returned
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<User> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
|
||||
bean-discovery-mode="all" version="3.0">
|
||||
</beans>
|
|
@ -0,0 +1,47 @@
|
|||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>MVC 2.0</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@100;200;300;600&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="${pageContext.request.contextPath}/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
||||
<div class="container-fluid">
|
||||
<span class="navbar-brand" href="#"><span style="font-size: 24px;">Baeldung - Eclipse Krazo</span></span>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
|
||||
aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-sm-7 mx-auto">
|
||||
<div class="card">
|
||||
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-success">User created successfully!</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,89 @@
|
|||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>MVC 2.0</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@100;200;300;600&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="${pageContext.request.contextPath}/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
||||
<div class="container-fluid">
|
||||
<span class="navbar-brand" href="#"><span style="font-size: 24px;">Baeldung - Eclipse Krazo</span></span>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
|
||||
aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-sm-7 mx-auto">
|
||||
<h3>
|
||||
<strong>User Details</strong>
|
||||
</h3>
|
||||
<hr class="hr-dark"/>
|
||||
<c:if test="${errors.size() > 0}">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<dl class="row">
|
||||
<c:forEach var="error" items="${errors}">
|
||||
<dt class="col-sm-2">${error.paramName}</dt>
|
||||
<dd class="col-sm-10">${error.message}</dd>
|
||||
</c:forEach>
|
||||
</dl>
|
||||
</div>
|
||||
</c:if>
|
||||
<form action="${mvc.basePath}/users" method="post">
|
||||
<div class="form-group row mt-3">
|
||||
<label for="name" class="col-sm-3 col-form-label">Name</label>
|
||||
<div class="col-sm-9">
|
||||
<input name="name" type="text" class="form-control" id="name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row mt-3">
|
||||
<label for="age" class="col-sm-3 col-form-label">Age</label>
|
||||
<div class="col-sm-9">
|
||||
<input name="age" type="text" class="form-control" id="age">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row mt-3">
|
||||
<label for="email" class="col-sm-3 col-form-label">Email</label>
|
||||
<div class="col-sm-9">
|
||||
<input name="email" type="email" class="form-control" id="email">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row mt-3">
|
||||
<label for="phone" class="col-sm-3 col-form-label">Phone</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="phone">
|
||||
</div>
|
||||
</div>
|
||||
<hr class="hr-dark"/>
|
||||
<div class="form-group row mt-3">
|
||||
<div class="col-sm-10">
|
||||
<button type="submit" class="btn btn-primary"><strong>Create</strong></button>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="${mvc.csrf.name}" value="${mvc.csrf.token}"/>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
body, html {
|
||||
font-family: Raleway, serif;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: #63b175 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
@media (max-width: 979px) {
|
||||
body {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hr-dark {
|
||||
border-top: 2px solid #000;
|
||||
margin-bottom: 20px;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.eclipse.krazo;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Dummy Test
|
||||
*/
|
||||
public class AppUnitTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package com.baeldung.eclipse.krazo;
|
||||
|
||||
import com.baeldung.eclipse.krazo.User;
|
||||
import com.baeldung.eclipse.krazo.UserController;
|
||||
import jakarta.mvc.Models;
|
||||
import jakarta.mvc.binding.BindingResult;
|
||||
import org.eclipse.krazo.core.ModelsImpl;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* The class contains unit tests. We do only unit tests. Most of the classes are mocked
|
||||
*/
|
||||
@DisplayName("Eclipse Krazo MVC 2.0 Test Suite")
|
||||
class UserControllerUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
UserController userController = new UserController();
|
||||
|
||||
@Mock
|
||||
Models models;
|
||||
|
||||
@Mock
|
||||
BindingResult bindingResult;
|
||||
|
||||
@BeforeEach
|
||||
public void setUpClass() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test Show Form")
|
||||
void whenShowForm_thenReturnViewName() {
|
||||
assertNotNull(userController.showForm());
|
||||
assertEquals("user.jsp", userController.showForm());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test Save User Success")
|
||||
void whenSaveUser_thenReturnSuccess() {
|
||||
when(bindingResult.isFailed()).thenReturn(false);
|
||||
|
||||
User user = new User();
|
||||
|
||||
assertNotNull(userController.saveUser(user));
|
||||
assertDoesNotThrow(() -> userController.saveUser(user));
|
||||
assertEquals("redirect:users/success", userController.saveUser(user));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test Save User Binding Errors")
|
||||
void whenSaveUser_thenReturnError() {
|
||||
when(bindingResult.isFailed()).thenReturn(true);
|
||||
Models testModels = new ModelsImpl();
|
||||
when(models.put(anyString(), any())).thenReturn(testModels);
|
||||
User user = getUser();
|
||||
assertNotNull(userController.saveUser(user));
|
||||
assertDoesNotThrow(() -> userController.saveUser(user));
|
||||
assertEquals("user.jsp", userController.saveUser(user));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test Save User Success View")
|
||||
void whenSaveUserSuccess_thenRedirectSuccess() {
|
||||
assertNotNull(userController.saveUserSuccess());
|
||||
assertDoesNotThrow(() -> userController.saveUserSuccess());
|
||||
assertEquals("success.jsp", userController.saveUserSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test Get Users API")
|
||||
void whenGetUser_thenReturnUsers() {
|
||||
when(bindingResult.isFailed()).thenReturn(false);
|
||||
|
||||
User user= getUser();
|
||||
|
||||
assertNotNull(user);
|
||||
assertEquals(30, user.getAge());
|
||||
assertEquals("john doe", user.getName());
|
||||
assertEquals("anymail", user.getEmail());
|
||||
assertEquals("99887766554433", user.getPhone());
|
||||
assertEquals("1", user.getId());
|
||||
|
||||
userController.saveUser(user);
|
||||
userController.saveUser(user);
|
||||
userController.saveUser(user);
|
||||
|
||||
assertNotNull(userController.getUsers());
|
||||
assertDoesNotThrow(() -> userController.getUsers());
|
||||
assertEquals(3, userController.getUsers().size());
|
||||
|
||||
}
|
||||
|
||||
private User getUser() {
|
||||
User user = new User();
|
||||
user.setId("1");
|
||||
user.setName("john doe");
|
||||
user.setAge(30);
|
||||
user.setEmail("anymail");
|
||||
user.setPhone("99887766554433");
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.baeldung</groupId>
|
||||
<artifactId>java-lite</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>java-lite</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.javalite</groupId>
|
||||
<artifactId>activeweb</artifactId>
|
||||
<version>${activeweb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.connector.java.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>${sun.tools.version}</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javalite</groupId>
|
||||
<artifactId>activeweb-testing</artifactId>
|
||||
<version>${activeweb-testing.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/webapp/WEB-INF</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>${jetty.maven.plugin.version}</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>activejdbc.log</name>
|
||||
</systemProperty>
|
||||
<systemProperty>
|
||||
<name>active_reload</name>
|
||||
<value>true</value>
|
||||
</systemProperty>
|
||||
<systemProperty>
|
||||
<name>activeweb.log.request</name>
|
||||
<value>true</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.javalite</groupId>
|
||||
<artifactId>activejdbc-instrumentation</artifactId>
|
||||
<version>${activejdbc.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>instrument</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jetty.maven.plugin.version>9.4.8.v20171121</jetty.maven.plugin.version>
|
||||
<activejdbc.version>1.4.13</activejdbc.version>
|
||||
<activeweb.version>1.15</activeweb.version>
|
||||
<mysql.connector.java.version>5.1.45</mysql.connector.java.version>
|
||||
<sun.tools.version>1.7.0</sun.tools.version>
|
||||
<activeweb-testing.version>1.15</activeweb-testing.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,8 @@
|
|||
## Servlets
|
||||
|
||||
This module contains articles about Servlets.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Check if a User Is Logged-in With Servlets and JSP](https://www.baeldung.com/servlets-jsp-check-user-login)
|
||||
- [How to Mock HttpServletRequest](https://www.baeldung.com/java-httpservletrequest-mock)
|
||||
- [Set a Parameter in an HttpServletRequest in Java](https://www.baeldung.com/java-servlet-request-set-parameter)
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.javax-servlets</groupId>
|
||||
<artifactId>javax-servlets-2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>javax-servlets-2</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- File Uploading -->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>${commons-fileupload.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>${commons-text.version}</version>
|
||||
</dependency>
|
||||
<!-- Servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${javax.servlet-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>javax.servlet.jsp-api</artifactId>
|
||||
<version>${javax.servlet.jsp-api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>${jstl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jmockit</groupId>
|
||||
<artifactId>jmockit</artifactId>
|
||||
<version>${jmockit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring-test.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${org.apache.httpcomponents.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
-javaagent:"${settings.localRepository}"/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>${jetty-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<webApp>
|
||||
<contextPath>/</contextPath>
|
||||
</webApp>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<org.apache.httpcomponents.version>4.5.13</org.apache.httpcomponents.version>
|
||||
<jmockit.version>1.49</jmockit.version>
|
||||
<spring-test.version>5.3.20</spring-test.version>
|
||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
||||
<jetty-maven-plugin.version>10.0.4</jetty-maven-plugin.version>
|
||||
<commons-text.version>1.10.0</commons-text.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet(name = "UserServlet", urlPatterns = "/user")
|
||||
public class UserServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 2923732283720972121L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
String firstName = request.getParameter("firstName");
|
||||
String lastName = request.getParameter("lastName");
|
||||
|
||||
response.getWriter()
|
||||
.append("Full Name: " + firstName + " " + lastName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.*;
|
||||
|
||||
@WebServlet(name = "LanguageServlet", urlPatterns = "/setparam/lang")
|
||||
public class LanguageServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
|
||||
SetParameterRequestWrapper requestWrapper = new SetParameterRequestWrapper(request);
|
||||
requestWrapper.setParameter("locale", Locale.getDefault().getLanguage());
|
||||
request.getRequestDispatcher("/setparam/3rd_party_module.jsp").forward(requestWrapper, response);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@WebFilter(urlPatterns = { "/setparam/with-sanitize.jsp" })
|
||||
public class SanitizeParametersFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest httpReq = (HttpServletRequest) request;
|
||||
chain.doFilter(new SanitizeParametersRequestWrapper(httpReq), response);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
|
||||
public class SanitizeParametersRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private final Map<String, String[]> sanitizedMap;
|
||||
|
||||
public SanitizeParametersRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
sanitizedMap = Collections.unmodifiableMap(
|
||||
request.getParameterMap().entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
entry -> Arrays.stream(entry.getValue())
|
||||
.map(StringEscapeUtils::escapeHtml4)
|
||||
.toArray(String[]::new)
|
||||
)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
return sanitizedMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
return Optional.ofNullable(getParameterMap().get(name))
|
||||
.map(values -> Arrays.copyOf(values, values.length))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
return Optional.ofNullable(getParameterValues(name))
|
||||
.map(values -> values[0])
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
public class SetParameterRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private final Map<String, String[]> paramMap;
|
||||
|
||||
public SetParameterRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
paramMap = new HashMap<>(request.getParameterMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
return Collections.unmodifiableMap(paramMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
return Optional.ofNullable(getParameterMap().get(name))
|
||||
.map(values -> Arrays.copyOf(values, values.length))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
return Optional.ofNullable(getParameterValues(name))
|
||||
.map(values -> values[0])
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public void setParameter(String name, String value) {
|
||||
paramMap.put(name, new String[] {value});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.baeldung.user.check;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @since 6 de fev de 2022
|
||||
* @author ulisses
|
||||
*/
|
||||
public class User implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected static final HashMap<String, User> DB = new HashMap<>();
|
||||
static {
|
||||
DB.put("admin", new User("admin", "password"));
|
||||
DB.put("user", new User("user", "pass"));
|
||||
}
|
||||
|
||||
private String name;
|
||||
private String password;
|
||||
|
||||
private List<Date> logins = new ArrayList<Date>();
|
||||
|
||||
public User(String name, String password) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Date> getLogins() {
|
||||
return logins;
|
||||
}
|
||||
|
||||
public void setLogins(List<Date> logins) {
|
||||
this.logins = logins;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
User other = (User) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.user.check;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebFilter("/user-check/*")
|
||||
public class UserCheckFilter implements Filter {
|
||||
public static void forward(HttpServletRequest request, HttpServletResponse response, String page) throws ServletException, IOException {
|
||||
request.getRequestDispatcher("/WEB-INF/user.check" + page)
|
||||
.forward(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
|
||||
if (!(req instanceof HttpServletRequest)) {
|
||||
throw new ServletException("Can only process HttpServletRequest");
|
||||
}
|
||||
|
||||
if (!(res instanceof HttpServletResponse)) {
|
||||
throw new ServletException("Can only process HttpServletResponse");
|
||||
}
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest) req;
|
||||
HttpServletResponse response = (HttpServletResponse) res;
|
||||
|
||||
request.setAttribute("origin", request.getRequestURI());
|
||||
|
||||
if (!request.getRequestURI()
|
||||
.contains("login") && request.getSession(false) == null) {
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
forward(request, response, "/login.jsp");
|
||||
// we return here so the original servlet is not processed
|
||||
return;
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
public void init(FilterConfig arg) throws ServletException {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.user.check;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@WebServlet("/user-check/login")
|
||||
public class UserCheckLoginServlet extends HttpServlet {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
if (request.getSession(false) != null) {
|
||||
response.sendRedirect(request.getContextPath() + "/user-check/home");
|
||||
return;
|
||||
}
|
||||
|
||||
String referer = (String) request.getAttribute("origin");
|
||||
request.setAttribute("origin", referer);
|
||||
UserCheckFilter.forward(request, response, "/login.jsp");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
String key = request.getParameter("name");
|
||||
String pass = request.getParameter("password");
|
||||
|
||||
User user = User.DB.get(key);
|
||||
if (user == null || !user.getPassword()
|
||||
.equals(pass)) {
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
request.setAttribute("origin", request.getParameter("origin"));
|
||||
request.setAttribute("error", "invalid login");
|
||||
UserCheckFilter.forward(request, response, "/login.jsp");
|
||||
return;
|
||||
}
|
||||
|
||||
user.getLogins()
|
||||
.add(new Date());
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
session.setAttribute("user", user);
|
||||
|
||||
String origin = request.getParameter("origin");
|
||||
if (origin == null || origin.contains("login"))
|
||||
origin = "./";
|
||||
|
||||
response.sendRedirect(origin);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.user.check;
|
||||
|
||||
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;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@WebServlet("/user-check/logout")
|
||||
public class UserCheckLogoutServlet extends HttpServlet {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session != null) {
|
||||
session.invalidate();
|
||||
}
|
||||
|
||||
request.setAttribute("loggedOut", true);
|
||||
response.sendRedirect("./");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.user.check;
|
||||
|
||||
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;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@WebServlet(name = "home", urlPatterns = { "/user-check/", "/user-check", "/user-check/home" })
|
||||
public class UserCheckServlet extends HttpServlet {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session == null || session.getAttribute("user") == null) {
|
||||
throw new IllegalStateException("user not logged in");
|
||||
}
|
||||
|
||||
User user = (User) session.getAttribute("user");
|
||||
request.setAttribute("user", user);
|
||||
|
||||
UserCheckFilter.forward(request, response, "/home.jsp");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,31 @@
|
|||
<%@ page contentType="text/html;charset=UTF-8" session="false"%>
|
||||
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>login success - current session info</title>
|
||||
</head>
|
||||
<body>
|
||||
<section>
|
||||
<h2>user info</h2>
|
||||
<div>
|
||||
<span>name: ${user.name}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span>logins:</span>
|
||||
<ul>
|
||||
<c:forEach var="login" items="${user.logins}">
|
||||
<li>${login}</li>
|
||||
</c:forEach>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="${pageContext.request.contextPath}/user-check/logout">
|
||||
logout
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<%@ page contentType="text/html;charset=UTF-8" session="false"%>
|
||||
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>login</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="${pageContext.request.contextPath}/user-check/login"
|
||||
method="POST">
|
||||
<input type="hidden" name="origin" value="${origin}">
|
||||
<c:if test="${not empty origin}">
|
||||
<div>* redirected to login from: ${origin}</div>
|
||||
</c:if>
|
||||
|
||||
<c:if test="${not empty error}">
|
||||
<div>* error: ${error}</div>
|
||||
</c:if>
|
||||
|
||||
<fieldset>
|
||||
<legend>credentials</legend>
|
||||
|
||||
<label for="name">name</label>
|
||||
<input type="text" name="name">
|
||||
|
||||
<label for="password">password</label>
|
||||
<input type="password" name="password">
|
||||
|
||||
<input type="submit">
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<%@ page import="java.util.*"%>
|
||||
<html>
|
||||
<head>
|
||||
<title>3rd party Module</title>
|
||||
</head>
|
||||
<body>
|
||||
<%
|
||||
String localeStr = request.getParameter("locale");
|
||||
Locale currentLocale = (localeStr != null ? new Locale(localeStr) : null);
|
||||
%>
|
||||
The language you have selected: <%=currentLocale != null ? currentLocale.getDisplayLanguage(currentLocale) : " None"%>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Sanitized request parameter</title>
|
||||
</head>
|
||||
<body>
|
||||
The text below comes from request parameter "input":
|
||||
<br/>
|
||||
<%=request.getParameter("input")%>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Non sanitized request parameter</title>
|
||||
</head>
|
||||
<body>
|
||||
The text below comes from request parameter "input":
|
||||
<br/>
|
||||
<%=request.getParameter("input")%>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,678 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpUpgradeHandler;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
public class TestUtil {
|
||||
|
||||
public static HttpServletRequest getRequest(Map<String, String[]> params) {
|
||||
return new HttpServletRequest() {
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync() throws IllegalStateException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object o) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerPort() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScheme() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestDispatcher getRequestDispatcher(String path) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemotePort() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteHost() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteAddr() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealPath(String path) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getParameterNames() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
String[] values = params.get(name);
|
||||
if (values == null || values.length == 0)
|
||||
return null;
|
||||
return values[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<Locale> getLocales() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalPort() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalAddr() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentLengthLong() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContentLength() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterEncoding() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getAttributeNames() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() throws ServletException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(String username, String password) throws ServletException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdValid() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdFromUrl() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdFromURL() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdFromCookie() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSession getSession(boolean create) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSession getSession() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletPath() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestedSessionId() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuffer getRequestURL() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestURI() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteUser() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryString() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathTranslated() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathInfo() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, ServletException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Part getPart(String name) throws IOException, ServletException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntHeader(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getHeaders(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getHeaderNames() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDateHeader(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cookie[] getCookies() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextPath() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String changeSessionId() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static HttpServletResponse getResponse(StringWriter writer) {
|
||||
|
||||
return new HttpServletResponse() {
|
||||
|
||||
@Override
|
||||
public void setLocale(Locale loc) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentType(String type) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLengthLong(long len) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentLength(int len) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterEncoding(String charset) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBufferSize(int size) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetBuffer() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCommitted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getWriter() throws IOException {
|
||||
return new PrintWriter(writer, isCommitted());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletOutputStream getOutputStream() throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterEncoding() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBufferSize() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushBuffer() throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(int sc, String sm) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(int sc) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIntHeader(String name, int value) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeader(String name, String value) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDateHeader(String name, long date) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRedirect(String location) throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendError(int sc, String msg) throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendError(int sc) throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getHeaders(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getHeaderNames() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeUrl(String url) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeURL(String url) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeRedirectUrl(String url) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeRedirectURL(String url) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsHeader(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIntHeader(String name, int value) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHeader(String name, String value) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDateHeader(String name, long date) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCookie(Cookie cookie) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import mockit.Expectations;
|
||||
import mockit.Mocked;
|
||||
|
||||
class UserServletUnitTest {
|
||||
|
||||
private UserServlet servlet;
|
||||
private StringWriter writer;
|
||||
|
||||
@Mocked
|
||||
HttpServletRequest mockRequest;
|
||||
@Mocked
|
||||
HttpServletResponse mockResponse;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
servlet = new UserServlet();
|
||||
writer = new StringWriter();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenHttpServletRequest_whenUsingAnonymousClass_thenReturnsParameterValues() throws IOException {
|
||||
final Map<String, String[]> params = new HashMap<>();
|
||||
params.put("firstName", new String[] { "Anonymous Class" });
|
||||
params.put("lastName", new String[] { "Test" });
|
||||
|
||||
servlet.doGet(TestUtil.getRequest(params), TestUtil.getResponse(writer));
|
||||
|
||||
assertThat(writer.toString()).isEqualTo("Full Name: Anonymous Class Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenHttpServletRequest_whenMockedWithMockito_thenReturnsParameterValues() throws IOException {
|
||||
// mock HttpServletRequest & HttpServletResponse
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
|
||||
// mock the returned value of request.getParameterMap()
|
||||
when(request.getParameter("firstName")).thenReturn("Mockito");
|
||||
when(request.getParameter("lastName")).thenReturn("Test");
|
||||
when(response.getWriter()).thenReturn(new PrintWriter(writer));
|
||||
|
||||
servlet.doGet(request, response);
|
||||
|
||||
assertThat(writer.toString()).isEqualTo("Full Name: Mockito Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenHttpServletRequest_whenMockedWithJMockit_thenReturnsParameterValues() throws IOException {
|
||||
|
||||
new Expectations() {{
|
||||
mockRequest.getParameter("firstName"); result = "JMockit";
|
||||
mockRequest.getParameter("lastName"); result = "Test";
|
||||
mockResponse.getWriter(); result = new PrintWriter(writer);
|
||||
}};
|
||||
|
||||
servlet.doGet(mockRequest, mockResponse);
|
||||
|
||||
assertThat(writer.toString()).isEqualTo("Full Name: JMockit Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenHttpServletRequest_whenUsingMockHttpServletRequest_thenReturnsParameterValues() throws IOException {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setParameter("firstName", "Spring");
|
||||
request.setParameter("lastName", "Test");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
servlet.doGet(request, response);
|
||||
|
||||
assertThat(response.getContentAsString()).isEqualTo("Full Name: Spring Test");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LanguageServletLiveTest {
|
||||
|
||||
@Test
|
||||
public void whenGetRequestUsingHttpClient_thenResponseBodyContainsDefaultLanguage() throws Exception {
|
||||
|
||||
// When
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet method = new HttpGet("http://localhost:8080/setparam/lang");
|
||||
HttpResponse httpResponse = client.execute(method);
|
||||
|
||||
// Then
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
String expectedLanguage = defaultLocale.getDisplayLanguage(defaultLocale);
|
||||
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
||||
assertTrue(responseBody.contains("The language you have selected: " + expectedLanguage));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SanitizeParametersRequestLiveTest {
|
||||
|
||||
private static String PARAM_INPUT;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws UnsupportedEncodingException {
|
||||
PARAM_INPUT = URLEncoder.encode("<script>alert('Hello');</script>", "UTF-8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInputParameterContainsXss_thenResponseBodyContainsSanitizedValue() throws Exception {
|
||||
|
||||
// When
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet method = new HttpGet(String.format("http://localhost:8080/setparam/with-sanitize.jsp?input=%s", PARAM_INPUT));
|
||||
HttpResponse httpResponse = client.execute(method);
|
||||
|
||||
// Then
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
||||
assertTrue(responseBody.contains("<script>alert('Hello');</script>"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SanitizeParametersRequestWrapperUnitTest {
|
||||
|
||||
private static final String NEW_VALUE = "NEW VALUE";
|
||||
|
||||
private Map<String, String[]> parameterMap;
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Before
|
||||
public void initBeforeEachTest() {
|
||||
parameterMap = new HashMap<>();
|
||||
parameterMap.put("input", new String[] {"<script>alert('Hello');</script>"});
|
||||
when(request.getParameterMap()).thenReturn(parameterMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetParameterViaWrapper_thenParameterReturnedIsSanitized() {
|
||||
SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request);
|
||||
String actualValue = wrapper.getParameter("input");
|
||||
|
||||
assertEquals("<script>alert('Hello');</script>", actualValue);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void whenPutValueToWrapperParameterMap_thenThrowsUnsupportedOperationException() {
|
||||
SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request);
|
||||
Map<String, String[]> wrapperParamMap = wrapper.getParameterMap();
|
||||
wrapperParamMap.put("input", new String[] {NEW_VALUE});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetValueToWrapperParametersStringArray_thenThe2ndCallShouldNotEqualToNewValue() {
|
||||
SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request);
|
||||
String[] firstCallValues = wrapper.getParameterValues("input");
|
||||
|
||||
firstCallValues[0] = NEW_VALUE;
|
||||
String[] secondCallValues = wrapper.getParameterValues("input");
|
||||
assertThat(secondCallValues).doesNotContain(NEW_VALUE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SetParameterRequestWrapperUnitTest {
|
||||
|
||||
private static final String NEW_VALUE = "NEW VALUE";
|
||||
|
||||
private Map<String, String[]> parameterMap;
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Before
|
||||
public void initBeforeEachTest() {
|
||||
parameterMap = new HashMap<>();
|
||||
parameterMap.put("input", new String[] {"inputValue"});
|
||||
when(request.getParameterMap()).thenReturn(parameterMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetParameterViaWrapper_thenGetParameterShouldReturnTheSameValue() {
|
||||
SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request);
|
||||
wrapper.setParameter("newInput", "newInputValue");
|
||||
String actualValue = wrapper.getParameter("newInput");
|
||||
|
||||
assertEquals("newInputValue", actualValue);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void whenPutValueToWrapperParameterMap_thenThrowsUnsupportedOperationException() {
|
||||
SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request);
|
||||
Map<String, String[]> wrapperParamMap = wrapper.getParameterMap();
|
||||
wrapperParamMap.put("input", new String[] {NEW_VALUE});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetValueToWrapperParametersStringArray_thenThe2ndCallShouldNotEqualToNewValue() {
|
||||
SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request);
|
||||
String[] firstCallValues = wrapper.getParameterValues("input");
|
||||
|
||||
firstCallValues[0] = NEW_VALUE;
|
||||
String[] secondCallValues = wrapper.getParameterValues("input");
|
||||
assertThat(secondCallValues).doesNotContain(NEW_VALUE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.setparam;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UnsanitizedParametersRequestLiveTest {
|
||||
|
||||
private static final String TAG_SCRIPT = "<script>alert('Hello');</script>";
|
||||
|
||||
private static String PARAM_INPUT;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws UnsupportedEncodingException {
|
||||
PARAM_INPUT = URLEncoder.encode(TAG_SCRIPT, "UTF-8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInputParameterContainsXss_thenResponseBodyContainsUnsanitizedValue() throws Exception {
|
||||
|
||||
// When
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet method = new HttpGet(String.format("http://localhost:8080/setparam/without-sanitize.jsp?input=%s", PARAM_INPUT));
|
||||
HttpResponse httpResponse = client.execute(method);
|
||||
|
||||
// Then
|
||||
HttpEntity entity = httpResponse.getEntity();
|
||||
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
||||
assertTrue(responseBody.contains(TAG_SCRIPT));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package com.baeldung.user.check;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.LaxRedirectStrategy;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class UserCheckServletLiveTest {
|
||||
private static final String BASE_URL = "http://localhost:8080/javax-servlets-2/user-check";
|
||||
|
||||
@Mock
|
||||
HttpServletRequest request;
|
||||
|
||||
@Mock
|
||||
HttpServletResponse response;
|
||||
|
||||
private CloseableHttpClient buildClient() {
|
||||
return HttpClientBuilder.create()
|
||||
.setRedirectStrategy(new LaxRedirectStrategy())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCorrectCredentials_thenLoginSucceeds() throws Exception {
|
||||
try (CloseableHttpClient client = buildClient()) {
|
||||
HttpPost post = new HttpPost(BASE_URL + "/login");
|
||||
|
||||
List<BasicNameValuePair> form = new ArrayList<>();
|
||||
form.add(new BasicNameValuePair("name", "admin"));
|
||||
form.add(new BasicNameValuePair("password", "password"));
|
||||
|
||||
post.setEntity(new UrlEncodedFormEntity(form));
|
||||
try (CloseableHttpResponse response = client.execute(post)) {
|
||||
String body = EntityUtils.toString(response.getEntity());
|
||||
|
||||
assertTrue(response.getStatusLine()
|
||||
.getStatusCode() == 200);
|
||||
|
||||
assertTrue(body.contains("login success"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenIncorrectCredentials_thenLoginFails() throws Exception {
|
||||
try (CloseableHttpClient client = buildClient()) {
|
||||
HttpPost post = new HttpPost(BASE_URL + "/login");
|
||||
|
||||
List<BasicNameValuePair> form = new ArrayList<>();
|
||||
form.add(new BasicNameValuePair("name", "admin"));
|
||||
form.add(new BasicNameValuePair("password", "invalid"));
|
||||
|
||||
post.setEntity(new UrlEncodedFormEntity(form));
|
||||
try (CloseableHttpResponse response = client.execute(post)) {
|
||||
String body = EntityUtils.toString(response.getEntity());
|
||||
|
||||
assertTrue(response.getStatusLine()
|
||||
.getStatusCode() == 401);
|
||||
|
||||
assertTrue(body.contains("invalid login"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNotLoggedIn_thenRedirectedToLoginPage() throws Exception {
|
||||
try (CloseableHttpClient client = buildClient()) {
|
||||
HttpGet get = new HttpGet(BASE_URL + "/home");
|
||||
|
||||
try (CloseableHttpResponse response = client.execute(get)) {
|
||||
String body = EntityUtils.toString(response.getEntity());
|
||||
|
||||
assertTrue(response.getStatusLine()
|
||||
.getStatusCode() == 401);
|
||||
|
||||
assertTrue(body.contains("redirected to login"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
## Servlets
|
||||
|
||||
This module contains articles about Servlets.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Introduction to Java Servlets](https://www.baeldung.com/intro-to-servlets)
|
||||
- [An MVC Example with Servlets and JSP](https://www.baeldung.com/mvc-servlet-jsp)
|
||||
- [Handling Cookies and a Session in a Java Servlet](https://www.baeldung.com/java-servlet-cookies-session)
|
||||
- [Uploading Files with Servlets and JSP](https://www.baeldung.com/upload-file-servlet)
|
||||
- [Example of Downloading File in a Servlet](https://www.baeldung.com/servlet-download-file)
|
||||
- [Returning a JSON Response from a Servlet](https://www.baeldung.com/servlet-json-response)
|
||||
- [Jakarta EE Servlet Exception Handling](https://www.baeldung.com/servlet-exceptions)
|
||||
- [Context and Servlet Initialization Parameters](https://www.baeldung.com/context-servlet-initialization-param)
|
||||
- [The Difference between getRequestURI and getPathInfo in HttpServletRequest](https://www.baeldung.com/http-servlet-request-requesturi-pathinfo)
|
||||
- [Difference Between request.getSession() and request.getSession(true)](https://www.baeldung.com/java-request-getsession)
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.javax-servlets</groupId>
|
||||
<artifactId>javax-servlets</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>javax-servlets</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- File Uploading -->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>${commons-fileupload.version}</version>
|
||||
</dependency>
|
||||
<!-- Servlet -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${javax.servlet-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${org.apache.httpcomponents.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<org.apache.httpcomponents.version>4.5.3</org.apache.httpcomponents.version>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@WebServlet(name = "FormServlet", urlPatterns = "/calculateServlet")
|
||||
public class FormServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
|
||||
String height = request.getParameter("height");
|
||||
String weight = request.getParameter("weight");
|
||||
try {
|
||||
double bmi = calculateBMI(Double.parseDouble(weight), Double.parseDouble(height));
|
||||
request.setAttribute("bmi", bmi);
|
||||
response.setHeader("Test", "Success");
|
||||
response.setHeader("BMI", String.valueOf(bmi));
|
||||
request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
|
||||
} catch (Exception e) {
|
||||
request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/index.jsp");
|
||||
dispatcher.forward(request, response);
|
||||
}
|
||||
|
||||
private Double calculateBMI(Double weight, Double height) {
|
||||
return weight / (height * height);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
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;
|
||||
|
||||
@WebServlet("/main")
|
||||
public class MainServlet extends HttpServlet {
|
||||
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
request.getRequestDispatcher("/WEB-INF/jsp/main.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@WebServlet("/update")
|
||||
public class UpdateServlet extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
|
||||
HttpSession session = request.getSession(false);
|
||||
|
||||
if (session != null) {
|
||||
|
||||
session.setAttribute("userName", request.getParameter("userName"));
|
||||
session.setAttribute("age", request.getParameter("age"));
|
||||
|
||||
request.setAttribute("sessionData", session);
|
||||
}
|
||||
|
||||
request.getRequestDispatcher("/WEB-INF/jsp/update.jsp").forward(request, response);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@WebServlet("/u_login")
|
||||
public class UserLoginServlet extends HttpServlet {
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
HttpSession session = request.getSession();
|
||||
|
||||
session.setAttribute("userId", request.getParameter("userId"));
|
||||
|
||||
request.setAttribute("id", session.getAttribute("userId"));
|
||||
|
||||
request.getRequestDispatcher("/WEB-INF/jsp/userlogin.jsp").forward(request, response);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.servlets;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebInitParam;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@WebServlet(name = "UserServlet", urlPatterns = "/userServlet", initParams={
|
||||
@WebInitParam(name="name", value="Not provided"),
|
||||
@WebInitParam(name="email", value="Not provided")})
|
||||
public class UserServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
processRequest(request, response);
|
||||
forwardRequest(request, response, "/WEB-INF/jsp/result.jsp");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
}
|
||||
|
||||
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
request.setAttribute("name", getRequestParameter(request, "name"));
|
||||
request.setAttribute("email", getRequestParameter(request, "email"));
|
||||
request.setAttribute("province", getContextParameter("province"));
|
||||
request.setAttribute("country", getContextParameter("country"));
|
||||
}
|
||||
|
||||
protected String getRequestParameter(HttpServletRequest request, String name) {
|
||||
String param = request.getParameter(name);
|
||||
return !param.isEmpty() ? param : getInitParameter(name);
|
||||
}
|
||||
|
||||
protected String getContextParameter(String name) {
|
||||
return getServletContext().getInitParameter(name);
|
||||
}
|
||||
|
||||
protected void forwardRequest(HttpServletRequest request, HttpServletResponse response, String path)
|
||||
throws ServletException, IOException {
|
||||
request.getRequestDispatcher(path).forward(request, response);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,15 @@
|
|||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="ISO-8859-1">
|
||||
</head>
|
||||
<body>
|
||||
<form action="u_login">
|
||||
<p>Enter your User Id and Password</p>
|
||||
User ID: <input type="text" name="userId" /><br />
|
||||
Password: <input type="password" name="password" /> <br /> <input type="submit" value="Login" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<%@ page contentType="text/html" pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>User Data</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>User Information</h2>
|
||||
<p><strong>Name:</strong> ${name}</p>
|
||||
<p><strong>Email:</strong> ${email}</p>
|
||||
<p><strong>Province:</strong> ${province}</p>
|
||||
<p><strong>Country:</strong> ${country}</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,17 @@
|
|||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="ISO-8859-1">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Hi, User : ${sessionData.getAttribute("userId")}
|
||||
|
||||
<br> Your User Data has been updated as below :
|
||||
<br> User Name: ${sessionData.getAttribute("userName")}
|
||||
<br> Age : ${sessionData.getAttribute("age")}
|
||||
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue