In Bean Validation, constraints can inherit from one another. Of course, this is not the same thing as one class inheriting from another because you cannot extend annotations. However, per convention, constraint annotations usually include a target of ElementType.ANNOTATION_TYPE.
When a constraint annotation is located, the Validator determines if the annotation definition is annotated with any other constraints. If so, it combines all the additional constraints with the logic defined by the original constraint (if any) into a single, composite constraint. In this sense, the constraint inherits all the constraints with which it is annotated. If for some reason you need to create a constraint that cannot be inherited, you simply omit ElementType.ANNOTATION_TYPE from the definition. With all this in mind, take a look at the @Email definition.
@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {})
@Pattern(regexp = "^[a-z0-9`!#$%^&*'{}?/+=|_~-]+(\\.[a-z0-9`!#$%^&*'{}?/+=|"
+ "_~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?)+(\\.[a-z0-9]" + "([a-z0-9-]*[a-z0-9])?)*$", flags =
{ Pattern.Flag.CASE_INSENSITIVE })
@ReportAsSingleViolation
public @interface Email
{
String message() default "{ml.javasopenblog.site.validation.Email.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,
ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
static @interface List
{
Email[] value();
}
}
There’s a lot going on here, so take a look at it line by line, starting with the annotations:
@Target : This annotation indicates which language features this annotation can be placed on. The values listed are pretty standard and should be used for most constraints.
@Retention : Indicates that the annotation must be retained at run time. If not, Bean Validation will not detect it.
@Documented : This means that the Javadoc of targets marked with this annotation should indicate the annotation’s presence. This is especially useful when programming in an IDE because it makes the contract more visible.
@Constraint : This is a must: It’s what indicates that this annotation represents a Bean Validation constraint, so all constraint definitions have to be annotated with this. Without this, your constraint is ignored. @Constraint also indicates which ConstraintValidator implementation or implementations are responsible for validating your constraint. However, in this case no ConstraintValidator is necessary.
@Pattern : This is another constraint, indicating that this constraint inherits the constraint declared with @Pattern. This is the same regular expression seen earlier, but now you won’t have to duplicate the regular expression every time you use it. You can just use the @Email annotation, instead.
@ReportAsSingleViolation : Indicates that the composite constraint should be considered one constraint and use @Email’s message instead of @Pattern’s message. It is very rare that you should ever create a constraint that inherits other constraints without using @ReportAsSingleViolation.
Within the annotation are three attributes: message, groups, and payload. These are the standard attributes that must be present in all constraints. Without one or more of these, use of @Email would result in a ConstraintDefinitionException. The @Email.List inner annotation, like all the bean validation list annotations, defines a way to specify multiple @Email constraints on a target.
The @NotBlank constraint looks nearly identical to @Email. For the most part, it has the same annotations, attributes, and features. Instead of being annotated with @Pattern, it’s annotated with @NotNull. In this case @NotBlank should imply non-null, so you inherit the @NotNull constraint to accomplish this. (If you anticipate needing to define targets that can be null but cannot be blank strings, you would simply remove @NotNull from this annotation.)
@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy =
{ NotBlankValidator.class })
@NotNull
@ReportAsSingleViolation
public @interface NotBlank
{
String message() default "{ml.javasopenblog.site.validation.NotBlank.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,
ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
static @interface List
{
NotBlank[] value();
}
}
However, unlike @Email, it can’t inherit all its functionality. It needs a ConstraintValidator to test whether the value is blank. The following NotBlankValidator class, declared in the @Constraint annotation on the @NotBlank annotation, accomplishes this.
public class NotBlankValidator implements ConstraintValidator<NotBlank, CharSequence>
{
@Override
public void initialize(NotBlank annotation)
{
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context)
{
if (value instanceof String)
return ((String) value).trim().length() > 0;
return value.toString().trim().length() > 0;
}
}
Labels
- OCPJP
- OCPJP 8
- Path
- Comparator
- Eclipse
- Archetypes
- Arrays
- BufferedReader
- BufferedWriter
- Comparable
- DataInputStream
- DataOutputStream
- DateTimeFormatter
- FileInputStream
- FileOutputStream
- FileReader
- FileWriter
- Files
- Logger
- Maven
- Paths
- Singleton
- StandardCopyOption
- Static nested class
- Threading
- ZonedDateTime
- enum
Friday, December 9, 2016
Thursday, December 8, 2016
Adding Constraint Validation Annotations to Your Beans
Although you can create your own constraint annotations any time you like, the Bean Validation API comes with several built-in annotations that satisfy the most common validation requirements.
These are all very simple constraints, but in many cases they are all you need to use. All these
constraints are in the package javax.validation.constraints.
@Null : You can apply this to any type, and it ensures that the annotated target is null.
@NotNull : You can also apply this to any type. It ensures that the target is not null.
@AssertTrue and @AssertFalse : These ensure that their annotated targets are true and false, respectively. As such, the field, parameter, or method (return value) that they annotate must be of the type boolean or Boolean. A null Boolean is considered valid for either constraint, so combine these with @NotNull if you do not accept null values.
@DecimalMax : This defines an upper limit for a numeric type, specified with the value attribute. It may annotate fields, parameters, and methods (return values) of type BigDecimal, BigInteger, CharSequence (String), byte, Byte, short, Short, int, Integer, long, and Long. The primitives double, Double, float, and Float are not supported due to precision concerns. CharSequences are converted to a decimal before validation, and null values are considered valid. The optional inclusive attribute specifies whether the test should be inclusive (less than or equal to) or exclusive (less than), and defaults to inclusive (true).
@DecimalMin : This is the counterpart to @DecimalMax. It applies to all the same types with the same rules. It also contains an inclusive attribute.
@Digits : You can use this to ensure that the annotated target is a parseable number (if it’s a CharSequence) and then tests the limits of that number’s parts (whether it’s a CharSequence, BigDecimal, BigInteger, byte, Byte, short, Short, int, Int, long, or Long). The mandatory integer attribute specifies the maximum number of integral digits (before the decimal point) allowed, whereas the required fraction attribute specifies the maximum number of fractional digits (after the decimal point) allowed. As always, null values are considered valid.
@Future : Ensures that the Date or Calendar field, parameter, or method (return value) is at some point in the future, however near or distant. As of Bean Validation 1.1, there is no support for Java 8 Date and Time API types. null values are considered valid.
@Past : Ensures that Date and Calendar targets are at some point in the past.
@Max and @Min : These are similar to @DecimalMax and @DecimalMin, but they do not support CharSequence targets, and they do not host an inclusive attribute; they are always inclusive. Targets that are null are considered valid.
@Pattern : This defines a regular expression regexp that the target CharSequence (String) must match, and it considers null values to be valid. It hosts an optional flags attribute that supports an array of any of Pattern.Flag enum values. Supported flags are:
CANON_EQ : Enables canonical equivalence
CASE_INSENSITIVE : Enables case-insensitive matching
COMMENTS : Enables white space and comments in the pattern
DOTALL : Turns dotall mode on
MULTILINE : Turns multiline mode on
UNICODE_CASE : Enables Unicode case folding
UNIX_LINES : Turns Unix lines mode on
@Size : This defines inclusive max and min limits for the length of a CharSequence (String), the number of values in a Collection, the number of entries in a Map, or the number of elements in an array of any type.
These are all very simple constraints, but in many cases they are all you need to use. All these
constraints are in the package javax.validation.constraints.
@Null : You can apply this to any type, and it ensures that the annotated target is null.
@NotNull : You can also apply this to any type. It ensures that the target is not null.
@AssertTrue and @AssertFalse : These ensure that their annotated targets are true and false, respectively. As such, the field, parameter, or method (return value) that they annotate must be of the type boolean or Boolean. A null Boolean is considered valid for either constraint, so combine these with @NotNull if you do not accept null values.
@DecimalMax : This defines an upper limit for a numeric type, specified with the value attribute. It may annotate fields, parameters, and methods (return values) of type BigDecimal, BigInteger, CharSequence (String), byte, Byte, short, Short, int, Integer, long, and Long. The primitives double, Double, float, and Float are not supported due to precision concerns. CharSequences are converted to a decimal before validation, and null values are considered valid. The optional inclusive attribute specifies whether the test should be inclusive (less than or equal to) or exclusive (less than), and defaults to inclusive (true).
@DecimalMin : This is the counterpart to @DecimalMax. It applies to all the same types with the same rules. It also contains an inclusive attribute.
@Digits : You can use this to ensure that the annotated target is a parseable number (if it’s a CharSequence) and then tests the limits of that number’s parts (whether it’s a CharSequence, BigDecimal, BigInteger, byte, Byte, short, Short, int, Int, long, or Long). The mandatory integer attribute specifies the maximum number of integral digits (before the decimal point) allowed, whereas the required fraction attribute specifies the maximum number of fractional digits (after the decimal point) allowed. As always, null values are considered valid.
@Future : Ensures that the Date or Calendar field, parameter, or method (return value) is at some point in the future, however near or distant. As of Bean Validation 1.1, there is no support for Java 8 Date and Time API types. null values are considered valid.
@Past : Ensures that Date and Calendar targets are at some point in the past.
@Max and @Min : These are similar to @DecimalMax and @DecimalMin, but they do not support CharSequence targets, and they do not host an inclusive attribute; they are always inclusive. Targets that are null are considered valid.
@Pattern : This defines a regular expression regexp that the target CharSequence (String) must match, and it considers null values to be valid. It hosts an optional flags attribute that supports an array of any of Pattern.Flag enum values. Supported flags are:
CANON_EQ : Enables canonical equivalence
CASE_INSENSITIVE : Enables case-insensitive matching
COMMENTS : Enables white space and comments in the pattern
DOTALL : Turns dotall mode on
MULTILINE : Turns multiline mode on
UNICODE_CASE : Enables Unicode case folding
UNIX_LINES : Turns Unix lines mode on
@Size : This defines inclusive max and min limits for the length of a CharSequence (String), the number of values in a Collection, the number of entries in a Map, or the number of elements in an array of any type.
Wednesday, December 7, 2016
Configuring Validation in the Spring Framework Container
At its simplest, configuring Spring Framework’s LocalValidatorFactoryBean is as simple as instantiating it and returning it in a @Bean method in the RootContextConfiguration class:
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
return new LocalValidatorFactoryBean();
}
The LocalValidatorFactoryBean automatically detects the Bean Validation implementation on the classpath, whether that’s Hibernate Validator or some other implementation, and uses its default javax.validation.ValidatorFactory as the backing factory. There’s no need to set up the META-INF/validation.xml file usually required to take advantage of Bean Validation in your application. However, sometimes there is more than one Bean Validation Provider on the classpath (for example, when running within a full Java EE application server such as GlassFish or WebSphere).
In these cases, which provider Spring selects is unpredictable (it might even change each time!), so you should set the provider class manually if you prefer the provider to be predictable.
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setProviderClass(HibernateValidator.class);
return validator;
}
The only downside to doing this is that it requires Hibernate Validator to be a compile-time dependency instead of a runtime dependency. This pollutes your compile time classpath, meaning your IDE will sometimes make code suggestions that you don’t want. You can avoid this by loading the class dynamically, which of course has its own downside in that any mistakes in the name will not be caught at compile time.
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
throws ClassNotFoundException
{
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setProviderClass(Class.forName(
"org.hibernate.validator.HibernateValidator"
));
return validator;
}
N.B. Setting the provider class manually is not necessary when using Tomcat.
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
return new LocalValidatorFactoryBean();
}
The LocalValidatorFactoryBean automatically detects the Bean Validation implementation on the classpath, whether that’s Hibernate Validator or some other implementation, and uses its default javax.validation.ValidatorFactory as the backing factory. There’s no need to set up the META-INF/validation.xml file usually required to take advantage of Bean Validation in your application. However, sometimes there is more than one Bean Validation Provider on the classpath (for example, when running within a full Java EE application server such as GlassFish or WebSphere).
In these cases, which provider Spring selects is unpredictable (it might even change each time!), so you should set the provider class manually if you prefer the provider to be predictable.
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setProviderClass(HibernateValidator.class);
return validator;
}
The only downside to doing this is that it requires Hibernate Validator to be a compile-time dependency instead of a runtime dependency. This pollutes your compile time classpath, meaning your IDE will sometimes make code suggestions that you don’t want. You can avoid this by loading the class dynamically, which of course has its own downside in that any mistakes in the name will not be caught at compile time.
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
throws ClassNotFoundException
{
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setProviderClass(Class.forName(
"org.hibernate.validator.HibernateValidator"
));
return validator;
}
N.B. Setting the provider class manually is not necessary when using Tomcat.
Saturday, November 5, 2016
Git from scratch in a nutshell
After downloading Git from https://git-scm.com/downloads and installing it on your machine, you should open the terminal and configure the username (the author) and the email within the global configuration:
Then, create a new project and convert it to a Git repository (versioned project) issuing git init command:
Or, by using Spring Tool Suite as shown below:
Now, let's create a new file within the project directory, then add it to staging area using git add <file> command. Afterwards, commit these changes to the repository's database using git commit -m <message> command:
Or, by using Spring Tool Suite as shown below:
In order to check your repo status, you might find the command git status -s very useful with the param s standing for short. On the other hand, you have the command git log --oneline with the param oneline for brevity's sake to check commit history.
One of the most brilliant features of Git is branching. Branching allows you to work on a different directory rather than working on the production's one, which is a bad practice. Now let's suppose you want to do some development and commit changes within a different branch named development. The following commands are useful for this purpose:
After making and committing your changes, you might want to merge these changes to the production directory(master branch) and delete the development branch. In order to do so, you could issue the following commands:
Pushing into GitHub
using
git pull origin <branch>
git push origin <branch>
commands:
Or, by using Spring Tool Suite as shown below:
Setting Up The Central Repository, And Multiple Development Environments
GitHub via SSH
In order to communicate with GitHub via SSH protocol rather than HTTPS(default), you should generate encryption keys using ssh-keygen -t <type> -b <lenght> - C <comment> command.
Afterward, you should start the SSH agent on your machine using eval "$(ssh-agent -s)" command and then add the SSH public key into it using ssh-add ~/.ssh/id_rsa.pub command.
Now copy the content of you public key file(~/.ssh/id_rsa.pub), head to GitHub.com, create new SSH key and paste that content into it.
You might verify the SSH connection using ssh -T -p 443 git@github.com command.
Now, in order to switch the protocol to SSH for the remote connection you should use git remote set-url origin git@github.com:<USERNAME>/<REPOSITORY>.git command. Afterward, you might check the effect of the previous command using git remote -v :
Then, create a new project and convert it to a Git repository (versioned project) issuing git init command:
Or, by using Spring Tool Suite as shown below:
Now, let's create a new file within the project directory, then add it to staging area using git add <file> command. Afterwards, commit these changes to the repository's database using git commit -m <message> command:
Or, by using Spring Tool Suite as shown below:
In order to check your repo status, you might find the command git status -s very useful with the param s standing for short. On the other hand, you have the command git log --oneline with the param oneline for brevity's sake to check commit history.
One of the most brilliant features of Git is branching. Branching allows you to work on a different directory rather than working on the production's one, which is a bad practice. Now let's suppose you want to do some development and commit changes within a different branch named development. The following commands are useful for this purpose:
or simply:$git branch development$git checkout development
$ git checkout -b development
These equivalent commands above, create a new branch named development and switch to it.After making and committing your changes, you might want to merge these changes to the production directory(master branch) and delete the development branch. In order to do so, you could issue the following commands:
$git checkout master$git merge development
$ git branch -d development
Pushing into GitHub
using
git pull origin <branch>
git push origin <branch>
commands:
Or, by using Spring Tool Suite as shown below:
Setting Up The Central Repository, And Multiple Development Environments
GitHub via SSH
In order to communicate with GitHub via SSH protocol rather than HTTPS(default), you should generate encryption keys using ssh-keygen -t <type> -b <lenght> - C <comment> command.
Afterward, you should start the SSH agent on your machine using eval "$(ssh-agent -s)" command and then add the SSH public key into it using ssh-add ~/.ssh/id_rsa.pub command.
Now copy the content of you public key file(~/.ssh/id_rsa.pub), head to GitHub.com, create new SSH key and paste that content into it.
You might verify the SSH connection using ssh -T -p 443 git@github.com command.
Now, in order to switch the protocol to SSH for the remote connection you should use git remote set-url origin git@github.com:<USERNAME>/<REPOSITORY>.git command. Afterward, you might check the effect of the previous command using git remote -v :
Configuring Sessions in the Deployment Descriptor
In many cases, HTTP sessions are ready to go in Java EE and require no explicit configuration. However, configure them you can, and for security purposes, you should. You configure sessions in the deployment descriptor using the <session-config> tag. Within this tag, you can configure the method by which sessions are tracked, the age after which sessions timeout, and the details of the session ID cookie, if you use that. Many of these have default values that you never need to change. The following code demonstrates all the possible deployment descriptor settings for sessions.
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>JSESSIONID</name>
<domain>example.org</domain>
<path>/shop</path>
<comment><![CDATA[Keeps you logged in. See our privacy policy for more information.]]></comment>
<http-only>true</http-only>
<secure>false</secure>
<max-age>1800</max-age>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
<tracking-mode>URL</tracking-mode>
<tracking-mode>SSL</tracking-mode>
</session-config>
All of the tags within <session-config> and <cookie-config> are optional, but they must appear in the order shown in this example (excluding omitted tags).
The <session-timeout> tag specifies how long sessions should remain inactive, in minutes, before being invalidated. If the value is 0 or less, the session never expires. If this tag is omitted, the container default applies. Tomcat’s default container is 30, which can be changed in the Tomcat configuration. If you want consistency, you should explicitly set the timeout using this tag. In this example the timeout is 30 minutes. Each time a user with a certain session ID makes a request to your application, the timer resets on his session’s inactivity. If he goes more than 30 minutes without making a request, his session is considered invalid and he is given a new session.
The <tracking-mode> tag, which was added in Servlet 3.0/Java EE 6, indicates which technique the container should use for tracking session IDs. The legal values are:
- URL : The container only embeds session IDs in URLs. It does not use cookies or SSL session IDs. This approach is not very secure.
- COOKIE : The container uses session cookies for tracking session IDs. This technique is very secure.
- SSL : The container uses SSL Session IDs as HTTP session IDs. This method is the most secure approach available but requires all requests to be HTTPS for it to work properly.
You may use <tracking-mode> more than once to tell the container it can use multiple strategies. For example, if you specify both COOKIE and URL, the container prefers cookies but uses URLs when cookies are not available. Specifying COOKIE as the only tracking mode tells the container to never embed sessions in URLs and always assume the user has cookies enabled. Likewise, specifying URL as the only tracking mode tells the container to never use cookies. If you enable the SSL tracking mode, you cannot also enable the COOKIE or URL modes. SSL Session IDs must be used on their own; the container cannot fall back to cookies or URLs in the absence of HTTPS.
The <cookie-config> tag applies only when COOKIE is specified as one of the (or the only) tracking modes. Tags within it customize the session cookies that the container returns to the browser:
- The <name> tag enables you to customize the name of the session cookie. The default is JSESSIONID, and you will probably never need to change that.
- The <domain> and <path> tags correspond to the Domain and Path attributes of the cookie. The web container appropriately defaults these for you so that you should usually not need to customize them. The Domain defaults to the domain name used to make the request during which the session was created. The Path defaults to the deployed application context name.
- The <comment> tag adds a Comment attribute to the session ID cookie, providing the opportunity to add arbitrary text. This is often used to explain the purpose of the cookie and point users to the site’s privacy policy. Whether you use this is entirely up to you. If you omit this tag, the Comment attribute is not added to the cookie.
- The <http-only> and <secure> tags correspond to the HttpOnly and Secure cookie attributes, and both default to false. For increased security, you should always customize <http-only> to true <secure> should be changed to true only if you have HTTPS enabled.
- The final tag, <max-age>, specifies the Max-Age cookie attribute that controls when the cookie expires. By default, the cookie has no expiration date, which means it expires when the browser closes. Setting this to -1 has the same effect. Expiring the cookie when the browser closes is almost always what you want. You customize this value in seconds (unlike <session-timeout>, which is in minutes), but doing so could cause the cookie to expire and session tracking to fail while the user is in the middle of actively using your application. It’s best to leave this one alone and not use this tag.
As of Servlet 3.0/Java EE 6, you can skip the deployment descriptor and configure most of these options programmatically using the ServletContext. Use the setSessionTrackingModes method to specify a Set of one or more javax.servlet.SessionTrackingMode enum constants. getSessionCookieConfig returns a javax.servlet.SessionCookieConfig use this object to configure any of the <cookie-config> settings. You can configure the tracking modes or cookie configuration only within a ServletContextListener’s contextInitialized method or a ServletContainerInitializer’s onStartup method. Currently, you cannot configure the session timeout programmatically this oversight should be corrected in Java EE 8.
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>JSESSIONID</name>
<domain>example.org</domain>
<path>/shop</path>
<comment><![CDATA[Keeps you logged in. See our privacy policy for more information.]]></comment>
<http-only>true</http-only>
<secure>false</secure>
<max-age>1800</max-age>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
<tracking-mode>URL</tracking-mode>
<tracking-mode>SSL</tracking-mode>
</session-config>
All of the tags within <session-config> and <cookie-config> are optional, but they must appear in the order shown in this example (excluding omitted tags).
The <session-timeout> tag specifies how long sessions should remain inactive, in minutes, before being invalidated. If the value is 0 or less, the session never expires. If this tag is omitted, the container default applies. Tomcat’s default container is 30, which can be changed in the Tomcat configuration. If you want consistency, you should explicitly set the timeout using this tag. In this example the timeout is 30 minutes. Each time a user with a certain session ID makes a request to your application, the timer resets on his session’s inactivity. If he goes more than 30 minutes without making a request, his session is considered invalid and he is given a new session.
The <tracking-mode> tag, which was added in Servlet 3.0/Java EE 6, indicates which technique the container should use for tracking session IDs. The legal values are:
- URL : The container only embeds session IDs in URLs. It does not use cookies or SSL session IDs. This approach is not very secure.
- COOKIE : The container uses session cookies for tracking session IDs. This technique is very secure.
- SSL : The container uses SSL Session IDs as HTTP session IDs. This method is the most secure approach available but requires all requests to be HTTPS for it to work properly.
You may use <tracking-mode> more than once to tell the container it can use multiple strategies. For example, if you specify both COOKIE and URL, the container prefers cookies but uses URLs when cookies are not available. Specifying COOKIE as the only tracking mode tells the container to never embed sessions in URLs and always assume the user has cookies enabled. Likewise, specifying URL as the only tracking mode tells the container to never use cookies. If you enable the SSL tracking mode, you cannot also enable the COOKIE or URL modes. SSL Session IDs must be used on their own; the container cannot fall back to cookies or URLs in the absence of HTTPS.
The <cookie-config> tag applies only when COOKIE is specified as one of the (or the only) tracking modes. Tags within it customize the session cookies that the container returns to the browser:
- The <name> tag enables you to customize the name of the session cookie. The default is JSESSIONID, and you will probably never need to change that.
- The <domain> and <path> tags correspond to the Domain and Path attributes of the cookie. The web container appropriately defaults these for you so that you should usually not need to customize them. The Domain defaults to the domain name used to make the request during which the session was created. The Path defaults to the deployed application context name.
- The <comment> tag adds a Comment attribute to the session ID cookie, providing the opportunity to add arbitrary text. This is often used to explain the purpose of the cookie and point users to the site’s privacy policy. Whether you use this is entirely up to you. If you omit this tag, the Comment attribute is not added to the cookie.
- The <http-only> and <secure> tags correspond to the HttpOnly and Secure cookie attributes, and both default to false. For increased security, you should always customize <http-only> to true <secure> should be changed to true only if you have HTTPS enabled.
- The final tag, <max-age>, specifies the Max-Age cookie attribute that controls when the cookie expires. By default, the cookie has no expiration date, which means it expires when the browser closes. Setting this to -1 has the same effect. Expiring the cookie when the browser closes is almost always what you want. You customize this value in seconds (unlike <session-timeout>, which is in minutes), but doing so could cause the cookie to expire and session tracking to fail while the user is in the middle of actively using your application. It’s best to leave this one alone and not use this tag.
As of Servlet 3.0/Java EE 6, you can skip the deployment descriptor and configure most of these options programmatically using the ServletContext. Use the setSessionTrackingModes method to specify a Set of one or more javax.servlet.SessionTrackingMode enum constants. getSessionCookieConfig returns a javax.servlet.SessionCookieConfig use this object to configure any of the <cookie-config> settings. You can configure the tracking modes or cookie configuration only within a ServletContextListener’s contextInitialized method or a ServletContainerInitializer’s onStartup method. Currently, you cannot configure the session timeout programmatically this oversight should be corrected in Java EE 8.
Monday, October 31, 2016
Debugging Tomcat from IntelliJ IDEA
If you use IntelliJ IDEA 14, you have just a few simple steps to take to get up and running with your web applications. The first thing you need to do is set up IntelliJ to recognize your local Tomcat or other container installation. This is a one-time-only step you set it up once in your global IDE settings, then you can use the application server for any web application project. Next, set up each web application project to use your configured container. Finally, you just need to start your application from IntelliJ and place breakpoints where you’d like to debug your application.
To start, you need to configure Tomcat in IntelliJ’s list of application servers.
1. Open up IntelliJ’s IDE settings dialog. With a project open you can go to File ➪ Settings, or click the Settings icon in the toolbar, or press Ctrl + Alt + S. If you don’t have a project open, you can click the Configure button and then the Settings button.
2. In the left pane of the Settings dialog, click Application Servers under IDE Settings. Initially, you have no application servers configured.
3. Click the green plus icon to add a new application server. Click the browse button next to the Tomcat Home field to browse for and select the Tomcat home directory (for example, C:\Tomcat 8.0). Then click OK. IntelliJ should automatically detect your Tomcat version.
4. Click OK again to complete adding Tomcat to your list of application servers, and change the name if you want.
5. Click Apply to save the changes and OK to close the Settings dialog.
After you create a project and are ready to deploy it to Tomcat from IntelliJ, you need to add a Tomcat run/debug configuration to your project.
1. Click the run/debug configurations icon (a down arrow) on the toolbar, then click Edit Configurations.
2. In the dialog that appears, click the green plus icon, scroll to the bottom of the Add New Configuration menu, hover over Tomcat Server, and click Local. This creates a run/debug configuration for running your project against a local Tomcat.
3. If Tomcat 8.0 is the only application server you have added to IntelliJ, it is automatically selected as the application server this run/debug configuration will use. If you have other application servers configured, one of those might be selected, in which case you need to click the “Application server” drop-down and select Tomcat 8.0 instead.
4. Name the run configuration something meaningful.
5. You’ll probably see a warning that no artifacts are marked for deployment. Correcting this is simple. Click the Deployment tab and then the green plus icon under the “Deploy at the server startup” heading. Click Artifact, and then click the exploded war file artifact. Click OK. Change the “Application context” name for the artifact deployment to the server relative URL you want it deployed to.
6. Click Apply and then OK to save the run/debug configuration and dismiss the dialog.
Now that you have set up Tomcat in IntelliJ and configured an IntelliJ project to run in Tomcat, you’re ready to start the application and debug it within your IDE.
1. Open your project with IntelliJ IDEA.
2. Make sure that its run/debug configuration is properly configured to use your local Tomcat 8.0 application server.
3. When opened, click the Debug icon on the toolbar (highlighted by the mouse pointer in the figure below) or press Shift + F9 to compile and start your application in debug mode. IntelliJ should launch your default browser, and you should immediately hit the breakpoints in index.jsp.
You should again see the webpage to indicate that your application successfully deployed.
To start, you need to configure Tomcat in IntelliJ’s list of application servers.
1. Open up IntelliJ’s IDE settings dialog. With a project open you can go to File ➪ Settings, or click the Settings icon in the toolbar, or press Ctrl + Alt + S. If you don’t have a project open, you can click the Configure button and then the Settings button.
2. In the left pane of the Settings dialog, click Application Servers under IDE Settings. Initially, you have no application servers configured.
3. Click the green plus icon to add a new application server. Click the browse button next to the Tomcat Home field to browse for and select the Tomcat home directory (for example, C:\Tomcat 8.0). Then click OK. IntelliJ should automatically detect your Tomcat version.
4. Click OK again to complete adding Tomcat to your list of application servers, and change the name if you want.
5. Click Apply to save the changes and OK to close the Settings dialog.
After you create a project and are ready to deploy it to Tomcat from IntelliJ, you need to add a Tomcat run/debug configuration to your project.
1. Click the run/debug configurations icon (a down arrow) on the toolbar, then click Edit Configurations.
2. In the dialog that appears, click the green plus icon, scroll to the bottom of the Add New Configuration menu, hover over Tomcat Server, and click Local. This creates a run/debug configuration for running your project against a local Tomcat.
3. If Tomcat 8.0 is the only application server you have added to IntelliJ, it is automatically selected as the application server this run/debug configuration will use. If you have other application servers configured, one of those might be selected, in which case you need to click the “Application server” drop-down and select Tomcat 8.0 instead.
4. Name the run configuration something meaningful.
5. You’ll probably see a warning that no artifacts are marked for deployment. Correcting this is simple. Click the Deployment tab and then the green plus icon under the “Deploy at the server startup” heading. Click Artifact, and then click the exploded war file artifact. Click OK. Change the “Application context” name for the artifact deployment to the server relative URL you want it deployed to.
6. Click Apply and then OK to save the run/debug configuration and dismiss the dialog.
Now that you have set up Tomcat in IntelliJ and configured an IntelliJ project to run in Tomcat, you’re ready to start the application and debug it within your IDE.
1. Open your project with IntelliJ IDEA.
2. Make sure that its run/debug configuration is properly configured to use your local Tomcat 8.0 application server.
3. When opened, click the Debug icon on the toolbar (highlighted by the mouse pointer in the figure below) or press Shift + F9 to compile and start your application in debug mode. IntelliJ should launch your default browser, and you should immediately hit the breakpoints in index.jsp.
You should again see the webpage to indicate that your application successfully deployed.
Installing Tomcat on Your Machine as a Command-Line Application
Most application developers need to run Tomcat only as a command-line application and usually only from their IDE. To do this, follow these steps:
1. Download the architecture-appropriate Windows zip (if you use Windows) or the non-Windows zip (if you use anything else) from the Tomcat 8.0 download page and unzip the directory.
2. Place the contents of the Tomcat directory in this zip file into the folder C:\Tomcat 8.0 on your local machine (or into the appropriate directory for a server in your operating system). For example, the webapps directory should now be located at C:\Tomcat 8.0\webapps.
3. If you use Windows 7 or newer, you need to change some permissions to make Tomcat accessible from your IDE. Right-click the Apache Software Foundation directory in C: and click Properties. On the Security tab, click the Edit button. Add your user or the Users group, and give that entry full control over the directory.
4. To configure Tomcat for its first use, start by opening the file conf/tomcat-users.xml in your favorite text editor. Place the following tag between the <tomcat-users> </tomcat-users> XML tags:
<user username="admin" password="admin" roles="manager-gui,admin-gui" />
5. Open the conf/web.xml file. Search the file for the text org.apache.jasper.servlet.JspServlet. Below the tag that contains this text are two <init-param> tags. Add the following init parameters below the existing init parameters:
<init-param>
<param-name>compilerSourceVM</param-name>
<param-value>1.8</param-value>
</init-param>
<init-param>
<param-name>compilerTargetVM</param-name>
<param-value>1.8</param-value>
</init-param>
By default, Tomcat 8.0 compiles JavaServer Pages files with Java SE 6 language support even if it runs on Java SE 8. These new Servlet init parameters instruct Tomcat to compile JSP files with Java SE 8 language features, instead.
6. After you make these changes and save these files, you should now be ready to start up Tomcat and make sure that it runs properly. Open up a command prompt and change your directory to the Tomcat home directory (C:\Tomcat 8.0).
7. Type the command echo %JAVA_HOME% (or echo $JAVA_HOME on a non-Windows operating system) and press Enter to check whether the JAVA_HOME environmental variable is properly set to your Java Development Kit (JDK) home directory. If it is not, configure the environmental variable, and then log out and back in before proceeding. Tomcat cannot run without this variable properly set.
8. Type the command bin\startup.bat (or bin/startup.sh if you do not use Windows) and press Enter. A Java console window should open showing the output of the running Tomcat process. After a few seconds, you should see the message “INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 1827 ms” or something similar in the console window. This means Tomcat has started properly.
9. Open your favorite Web browser and navigate to http://localhost:8080/. You should see a page that looks like Figure below. This means that Tomcat is running and JSPs are compiling properly with Java SE 8. If this screen does not come up or you observe an error in the Java console, you need to check the preceding steps and possibly consult the Tomcat documentation.
When you finish using Tomcat, you can stop it by running the command bin\shutdown.bat (or bin/shutdown.sh) in the command prompt in the Tomcat 8.0 home directory. The Java console window should close, and Tomcat will stop.
1. Download the architecture-appropriate Windows zip (if you use Windows) or the non-Windows zip (if you use anything else) from the Tomcat 8.0 download page and unzip the directory.
2. Place the contents of the Tomcat directory in this zip file into the folder C:\Tomcat 8.0 on your local machine (or into the appropriate directory for a server in your operating system). For example, the webapps directory should now be located at C:\Tomcat 8.0\webapps.
3. If you use Windows 7 or newer, you need to change some permissions to make Tomcat accessible from your IDE. Right-click the Apache Software Foundation directory in C: and click Properties. On the Security tab, click the Edit button. Add your user or the Users group, and give that entry full control over the directory.
4. To configure Tomcat for its first use, start by opening the file conf/tomcat-users.xml in your favorite text editor. Place the following tag between the <tomcat-users> </tomcat-users> XML tags:
<user username="admin" password="admin" roles="manager-gui,admin-gui" />
5. Open the conf/web.xml file. Search the file for the text org.apache.jasper.servlet.JspServlet. Below the tag that contains this text are two <init-param> tags. Add the following init parameters below the existing init parameters:
<init-param>
<param-name>compilerSourceVM</param-name>
<param-value>1.8</param-value>
</init-param>
<init-param>
<param-name>compilerTargetVM</param-name>
<param-value>1.8</param-value>
</init-param>
By default, Tomcat 8.0 compiles JavaServer Pages files with Java SE 6 language support even if it runs on Java SE 8. These new Servlet init parameters instruct Tomcat to compile JSP files with Java SE 8 language features, instead.
6. After you make these changes and save these files, you should now be ready to start up Tomcat and make sure that it runs properly. Open up a command prompt and change your directory to the Tomcat home directory (C:\Tomcat 8.0).
7. Type the command echo %JAVA_HOME% (or echo $JAVA_HOME on a non-Windows operating system) and press Enter to check whether the JAVA_HOME environmental variable is properly set to your Java Development Kit (JDK) home directory. If it is not, configure the environmental variable, and then log out and back in before proceeding. Tomcat cannot run without this variable properly set.
8. Type the command bin\startup.bat (or bin/startup.sh if you do not use Windows) and press Enter. A Java console window should open showing the output of the running Tomcat process. After a few seconds, you should see the message “INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 1827 ms” or something similar in the console window. This means Tomcat has started properly.
9. Open your favorite Web browser and navigate to http://localhost:8080/. You should see a page that looks like Figure below. This means that Tomcat is running and JSPs are compiling properly with Java SE 8. If this screen does not come up or you observe an error in the Java console, you need to check the preceding steps and possibly consult the Tomcat documentation.
When you finish using Tomcat, you can stop it by running the command bin\shutdown.bat (or bin/shutdown.sh) in the command prompt in the Tomcat 8.0 home directory. The Java console window should close, and Tomcat will stop.
Subscribe to:
Posts (Atom)













































