删除编译错误
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