7.19. JSP Custom Tags

Table of contents

This function provides custom tags supporting creation of screens for web applications.

Custom tags have the following limitations:

  • They function in web containers supporting JSP 2.1 and above.
  • They use JSTL for controlling conditional branches and loops etc.
  • They support attributes compatible with XHTML 1.0 Transitional.
  • It is required to have JavaScript in the client. (See Adding a process before submission)
  • Some custom tags cannot be used with GET request. (See Using GET request)

Important

Attributes added in HTML5 can be described using dynamic attribute . However, the following attributes that are likely to be used frequently are defined as custom tag attributes in advance. In addition, each input element added in HTML5 has the following tags added based on text tag . Since the attributes specific to each input element are not defined individually in the custom tag, they need to be specified by dynamic attributes.

  • added attributes (Write the HTML tag name with the attribute added in the parentheses.)
  • autocomplete(input、password、form)
  • autofocus(input、textarea、select、button)
  • placeholder(text、password、textarea)
  • maxlength(textarea)
  • multiple(input)
  • added input elements

Important

Custom tags are meant for web applications in which simple screen transition as shown below is performed. For this reason, custom tags are not compatible with creation of screens with rich content focusing on operability and SPAs (Single Page Application).

  • Search screen → Search/Detail Display based on detail screen
  • Register/Update/Delete using Input Screen → Confirmation Screen → Completion Screen
  • Input assistance by pop-up (separate windows and separate tabs)

When JavaScript is frequently used in a project, be careful so that JavaScript output by the custom tags and JavaScript created in the project do not produce any side effects. Refer to Adding a process before submission for JavaScript output by the custom tags.

7.19.2. Function overview

7.19.2.1. Prevent omission of HTML escape

In HTML, characters such as “<”, “>” and “”” have a special meaning. Hence, if values containing these characters are output as it is in JSP, then a malicious user can easily inject a script, which leads to a vulnerability called Cross-Site Scripting (XSS). Therefore, perform HTML escape when input values are output.

However, if values are output using EL expression in JSP, HTML escape is not performed. For this reason, when values are output, it is always necessary that HTML escape is taken into consideration during implementation, which leads to reduced productivity.

Since HTML escape is performed by default in custom tags, as long as custom tags are used for implementation, HTML escape cannot be skipped.

Important

Since escape processing is not provided for JavaScript, dynamic values (input data, etc.) must not be embedded in the part where JavaScript is written, such as the script tag body and onclick attribute, etc. When embedding dynamic values (such as input data, etc.) in the part where JavaScript is written, the escape process should be performed at a project level.

See below for details of HTML escape.

7.19.2.2. Reduce implementation by having common JSP for input screen and confirmation screen

In many systems, the layout is the same for input screen and confirmation screen, and similar JSPs are created.

Since custom tags provide a function by which it is possible to have common JSP for input screen and confirmation screen, confirmation screen can be created by adding only the features (e.g. buttons etc.) that are specific to the confirmation screen on the JSP created for the input screen, and improvement in productivity can be expected.

See below for how to create a common JSP for input screen and confirmation screen.

7.19.3. Module list

<dependency>
  <groupId>com.nablarch.framework</groupId>
  <artifactId>nablarch-fw-web-tag</artifactId>
</dependency>

<!-- Only when using hidden encryption -->
<dependency>
  <groupId>com.nablarch.framework</groupId>
  <artifactId>nablarch-common-encryption</artifactId>
</dependency>

<!-- Only when using file download -->
<dependency>
  <groupId>com.nablarch.framework</groupId>
  <artifactId>nablarch-fw-web-extension</artifactId>
</dependency>

7.19.4. How to use

Tip

Since all attributes have not been described in the description of custom tags, refer to Tag Reference for attributes that can be specified for each custom tag.

7.19.4.1. Configure custom tags

Custom tags are configured using Nablarch Custom Tag Control Handler and CustomTagConfig.

Nablarch Custom Tag Control Handler

Handler for pre-process that is required for the following functions when processing of requests that use custom tags. Configuring this handler is required when using custom tags.

Refer to Nablarch Custom Tag Control Handler for values to be configured in this handler.

CustomTagConfig

Class in which default values of custom tags are configured. Sometimes, for custom tag attributes such as label pattern etc. of a selection item, default values that are standardized throughout the application rather than configuring the values each time on individual screens may be required. Therefore, the default values of custom tags are configured in this class.

For configuration of default values, add this class to component definition with the name customTagConfig. For configuration items, refer to CustomTagConfig.

7.19.4.2. Using custom tags (method of specifying taglib directive)

Since it is assumed that custom tags and JSTL will be used, specify the taglib directive for each.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="n" uri="http://tis.co.jp/nablarch" %>

7.19.4.3. Create an input form

The input form is created using the following custom tags. For more information on the custom tags listed below, see Tag Reference.

Points for creating an input form

Restoration of input values
When the input form is redisplayed due to validation error etc., input values are restored from the request parameters associated with the custom tags.
Output of the initial value
To output the initial value in the input item, set the object with initial value set in the request scope of the action. Specify the name attribute such that the name attribute of the custom tag corresponds to the variable name in the request scope. Refer to Rules to access input/output data for details of the specification method and implementation example.
Specifying submit URI
In custom tags, each of the multiple buttons/links placed on a form can be submitted to a different URI. URIs to which buttons/links are submitted, are specified to uri attribute. Refer to URI specification method for details of the specification method and implementation example.
Implementation examples

<n:form>
  <div>
    <label>User ID</label>
    <n:text name="form.userId" />
    <n:error name="form.userId" messageFormat="span" errorCss="alert alert-danger" />
  </div>
  <div>
    <label>Password</label>
    <n:password name="form.password" />
    <n:error name="form.password" messageFormat="span" errorCss="alert alert-danger" />
  </div>
  <div style="padding: 8px 0;">
    <n:submit type="submit" uri="/action/login" value="Login" />
  </div>
</n:form>
Output result

../../../_images/login_form.png

Tip

The name attribute of form tag has the following limitations:

  • Specify a unique name for the name attribute within the screen
  • Specify a value in accordance with the variable name syntax of JavaScript
Specify a unique name for the name attribute within the screen

In custom tags, JavaScript is used for controlling Submit. Refer to Adding a process before submission for JavaScript.

In this JavaScript, name attribute of form tag is used for identifying the form to be submitted. Therefore, when specifying the name attribute of form tag, it is necessary to specify a unique name for the name attribute within the screen.

If name attribute of form tag is not specified in the application, then the custom tag configures a unique value for the name attribute.

Specify a value in accordance with the variable name syntax of JavaScript

Since name attribute of form tag is used by JavaScript, it is necessary to specify a value in accordance with the variable name syntax of JavaScript.

Variable name syntax
  • Starts with an English alphabet
  • Subsequent values are alphanumeric or underscores

7.19.4.4. Displaying selection items (pull-down/radio button/check box)

The following custom tags are used for selection items:

Configure the options list (list of objects having the labels and values of options) in the request scope for the action and display the options list using the custom tags.

Tip

Selection state is determined after performing Object#toString for both selected value and option value.

Implementation examples

Option class

public class Plan {

    // Option values
    private String planId;

    // Option labels
    private String planName;

    public Plan(String planId, String planName) {
        this.planId = planId;
        this.planName = planName;
    }

    // Custom tags acquire the option values from this property.
    public String getPlanId() {
        return planId;
    }

    // Custom tags acquire the option labels from this property.
    public String getPlanName() {
        return planName;
    }
}
Action

// Configure the options list in the request scope.
List<Plan> plans = Arrays.asList(new Plan("A", "Free"),
                                 new Plan("B", "Basic"),
                                 new Plan("C", "Premium"));

// Custom tags acquire the options list from the request scope using the name specified here.
context.setRequestScopedVar("plans", plans);
Pull-down
JSP
<!--
  Access the contents of the options by specifying the following attributes.
  listName attribute: Name of the options list
  elementLabelProperty attribute: Property name showing the label
  elementValueProperty attribute: Property name showing the value
-->
<n:select name="form.plan1"
          listName="plans"
          elementLabelProperty="planName"
          elementValueProperty="planId" />
Output HTML
<!--
  When the value of "form.plan1" is "A".
-->
<select name="form.plan1">
  <option value="A" selected="selected">Free</option>
  <option value="B">Basic</option>
  <option value="C">Premium</option>
</select>
Radio button
JSP
<!—- Specification of the attribute is same as the select tag. -->
<n:radioButtons name="form.plan2"
                listName="plans"
                elementLabelProperty="planName"
                elementValueProperty="planId" />
Output HTML
<!--
 When the value of "form.plan2" is "B".
 Output using br tag if default.
 listFormat attribute can be specified and changed to div tag, span tag, ul tag, ol tag and space delimiter.
-->
<input id="nablarch_radio1" type="radio" name="form.plan2" value="A" />
<label for="nablarch_radio1">Free</label><br />
<input id="nablarch_radio2" type="radio" name="form.plan2" value="B" checked="checked" />
<label for="nablarch_radio2">Basic</label><br />
<input id="nablarch_radio3" type="radio" name="form.plan2" value="C" />
<label for="nablarch_radio3">Premium</label><br />
Checkbox
JSP
<!—- Specification of the attribute is same as the select tag. -->
<n:checkboxes name="form.plan4"
              listName="plans"
              elementLabelProperty="planName"
              elementValueProperty="planId" />
Output HTML
<!--
 When the value of "form.plan4" is "C".
 Output using br tag if default.
 listFormat attribute can be specified and changed to div tag, span tag, ul tag, ol tag and space delimiter.
-->
<input id="nablarch_checkbox1" type="checkbox" name="form.plan4" value="A"
       checked="checked" />
<label for="nablarch_checkbox1">Free</label><br />
<input id="nablarch_checkbox2" type="checkbox" name="form.plan4" value="B" />
<label for="nablarch_checkbox2">Basic</label><br />
<input id="nablarch_checkbox3" type="checkbox" name="form.plan4" value="C" />
<label for="nablarch_checkbox3">Premium</label><br />

Important

While on one hand, radioButtons tag and checkbox tag can easily output selection items, on the other hand, all options are output in the custom tags; hence there is always a limitation on the HTML that is output. When design cannot be controlled in the project, such as carrying out development based on the HTML created by a design company, there are cases where the HTML output by radioButtons tag and checkbox tag does not match with the design.

In such cases, if implementation is carried out using c:forEach tag of JSTL and radioButton tag or checkbox tag, then HTML displaying the options can be implemented without restriction.

<c:forEach items="${plans}" var="plan">
  <!-- HTML of users choice can be added before and after. -->
  <n:radioButton name="form.plan3" label="${plan.planName}" value="${plan.planId}" />
</c:forEach>

7.19.4.5. Specify the value for unchecked checkboxes

In the HTML checkbox tag, request parameter is not sent when checkboxes are unchecked. When using the checkbox tag for a single input item, the checkbox tag often corresponds to a data item expressed as a flag in the database, and usually some value is configured to it even in the unchecked state. Therefore, a function is provided in the checkbox tag, which enables specification of a value corresponding to the unchecked state.

Implementation examples
<!--
 By specifying the following attribute, actions in the case of unchecked state are controlled.
 useOffValue attribute: Whether to use the value configuration without the checkmark. Default is true
                        Specify false in the case of multiple selection for bulk deletion, etc.
 offLabel attribute: The label used when there is no checkmark.
                     The label displayed on the confirmation screen when a common JSP is used for the input and confirmation screens.
 offValue attribute: The value used when there is no checkmark. Default is 0.
-->
<n:checkbox name="form.useMail" value="true" label="Used"
            offLabel="Not used" offValue="false" />

Tip

This function is implemented using Nablarch Custom Tag Control Handler and hidden encryption. When the checkbox tag is output, the value corresponding to the unchecked state is output in the hidden tag, and when Nablarch Custom Tag Control Handler receives the request, the value corresponding to the unchecked state is configured in the request parameter only if the checkbox tag is unchecked.

7.19.4.6. Retaining the input data across screens (window scope)

Important

There are two methods to retain input data, the method explained here, in which window scope is used, and the method in which Session Store of library is used. Session Store should be used to retain input data across screens for the following reasons:

  • In window scope, a Bean cannot be stored as it is, since data is retained in key/value pairs. If data retained by a Bean is to be stored, the data will be fragmented, and implementation will become very complicated.

    // Let us assume such a Bean.
    Person person = new Person();
    person.setName("Name");
    person.setAge("Age");
    
    // Set to window scope (when done using action)
    request.setParam("person.name", person.getName());
    request.setParam("person.age", person.getAge());
    
    // Set to window scope (when done using JSP)
    <n:hidden name="person.name" />
    <n:hidden name="person.age" />
    
  • Since input data is configured to the window scope by specifying custom tag attributes, movement of data is difficult to comprehend. (degree of difficulty of implementation is high)

Input data is retained on the client as hidden tag. Compared to retaining the data in the server (session), when data is retained on the client, there are less restrictions on using the browser, such as use of multiple windows and use of the back button on the browser, and it becomes possible to have a flexible screen design.

The storage destination of data retained in the client is called a window scope. The data in the window scope is encrypted using hidden encryption.

Important

The data in the window scope is encrypted using hidden encryption and output in the hidden tag. Therefore, the contents of the window scope cannot be overwritten in the client, such as overwriting with the data acquired using Ajax.

Data is configured to the window scope by specifying windowScopePrefixes attribute of form tag.

Important

When windowScopePrefixes attribute is specified, among the request parameters, those with prefix match of the parameter name matching with the value specified for this attribute are configured to the window scope.

For example, if windowScopePrefixes="user" is specified, then the parameters that start with users are also configured to the window scope.

Implementation examples

Search condition of search function and input data of update function are retained across screens. Screen transition and movement of the data stored in hidden are as follows:

../../../_images/window_scope.png

The request parameter of the search condition is searchCondition.* and that of the input data is user.*.

Search screen
<!-- Data in the window scope is not sent. -->
<n:form>
Update screen
<!-- Only search condition is sent. -->
<n:form windowScopePrefixes="searchCondition">
Update confirmation screen
<!--
  Search condition and input data are sent.
  When specifying more than one, separate by comma.
-->
<n:form windowScopePrefixes="searchCondition,user">
Update completion screen
<!-- Only search condition is sent. -->
<n:form windowScopePrefixes="searchCondition">

Important

Data in the database should be kept to the necessary minimum, such as the primary key for identifying the data to be updated, data for optimistic locking, etc. Especially, data that is displayed on the input screen and confirmation screen (items only to be displayed and not the input items) should be acquired from the database whenever required rather than passing the data using hidden. If there is too much of data in hidden, communication speed will decrease and this can result in insufficient memory.

Important

The data stored in the window scope is output in the hidden tag and passed across screens as request parameters. Therefore, when using the data stored in the window scope for the action, it is necessary to perform validation.

Tip

In form tag, instead of uniform output of all request parameters in the hidden tag, request parameters that have already been output as input items are excluded from the output in the hidden tag.

Tip

Information such as login information, that is necessary for all tasks is retained in the server (session).

7.19.4.7. Encryption of data held in the client (hidden encryption)

The values of window scope and hidden tag can be tampered with in the client or can be easily referenced from the HTML source. For this reason, hidden encryption function is provided in the custom tags with the goal to prevent the hidden tag from being tampered or referenced.

Encryption is performed for all form tag, and decryption and tampering check are performed for all requests by default. Therefore, the application programmer need not implement hidden encryption function.

Important

Since the specifications are complicated and cannot be used easily, and also, since the use of encrypted data, such as the data in the window scope is deprecated, this function is also deprecated. Therefore, useHiddenEncryption should be configured to false, unless there is a particular reason.

hidden encryption

Hidden encryption is implemented via form tag and Nablarch Custom Tag Control Handler. The image of hidden encryption process is shown below: Encryption is performed through form tag, and decryption and tampering check are performed via Nablarch Custom Tag Control Handler.

../../../_images/hidden_encryption.png

Encryption process

Encryption is performed by the class that implements Encryptor interface. In the framework, AES (128bit) is used as a default encryption algorithm. To change the encryption algorithm, add the class that implements Encryptor to the component definition with the name hiddenEncryptor.

In encryption, for each form tag, the following data contained in form tag is collectively encrypted and output in 1 hidden tag.

In encryption, a hash value generated from the above data is included to detect tampering. The request ID is used to detect tampering when encrypted values are replaced across different input forms, while the hash value is used for detecting tampering by overwriting of values. The encrypted data is encoded using BASE64 and output in the hidden tag.

Tip

Since the hidden parameter explicitly specified in the custom tag hidden tag is included in the encryption, the value cannot be manipulated using JavaScript in the client. To manipulate the hidden parameter using JavaScript in the client, output the unencrypted hidden tag, using plainHidden tag.

Decryption process

The decryption process is performed through Nablarch Custom Tag Control Handler. The following cases are judged as tampering by the Nablarch Custom Tag Control Handler, and the screen is transitioned to the screen specified in the configuration.

  • Encrypted hidden parameter (nablarch_hidden) does not exist.
  • Decoding of BASE64 fails.
  • Decryption fails.
  • The hash value generated during encryption and hash value generated using the decrypted value do not match.
  • The request ID added during encryption and request ID of the received request do not match.
Storage location of the key used for encryption
The key used for encryption is generated for each session to minimize the expiry interval of the key as much as possible. Therefore, if the same user logs in again, the process cannot be continued from the screen used before the login.
hidden encryption configuration

In hidden encryption, the following can be configured by Configure custom tags:

useHiddenEncryption property
Whether to use hidden encryption. Default is true.
noHiddenEncryptionRequestIds property
Request ID for which hidden encryption is not performed.

Specify the requests for which hidden encryption cannot be used, to noHiddenEncryptionRequestIds property, as shown below:

  • Requests such as login screen, which serve as entry to an application
  • Requests transitioning from bookmarks
  • Requests transitioning from external sites

Since these requests do not have the encrypted hidden parameter (nablarch_hidden) or the key generated for each session, a tampering error will occur if noHiddenEncryptionRequestIds property is not configured.

The value configured in the noHiddenEncryptionRequestIds property is referenced by form tag and Nablarch Custom Tag Control Handler when performing the encryption and decryption process respectively.

form tag
Encryption is performed if at least one request ID to be encrypted is included in the form tag. Conversely, if a request ID to be encrypted is not included, encryption is not performed for the form tag.
Nablarch Custom Tag Control Handler
Decryption is performed only when the requested request ID has been encrypted.

7.19.4.8. Creating radio buttons and checkboxes associated with a composite key

When selecting data on the list screen, radio buttons and checkboxes are used. If a single value identifies the data, then radioButton tag and checkbox tag can be used, however, implementation is not easy in the case of a composite key.

In custom tags, radio buttons and checkboxes supporting composite keys are provided.

Important

To use this function, it is necessary to add CompositeKeyConvertor and CompositeKeyArrayConvertor to the component definition. For the configuration method, refer to Configuring Validators and Convertors for Use.

Important

This function works only with Nablarch Validation as CompositeKeyConvertor and CompositeKeyArrayConvertor are used. Does not support Bean Validation.

Implementation examples

Implementation method is explained based on an example in which a checkbox with a composite key is used for list display.

Form

In the form, property that holds the composite key is defined as CompositeKey.

public class OrderItemsForm {

    // This time, since a composite key for multiple data is received in the list display,
    // it is defined as a string.
    public CompositeKey[] orderItems;

    // Getter, constructor, etc. are omitted.

    // Specify the size of the composite key in the CompositeKeyType annotation.
    @CompositeKeyType(keySize = 2)
    public void setOrderItems(CompositeKey[] orderItems) {
        this.orderItems = orderItems;
    }
}
JSP
<table>
  <thead>
    <tr>
      <!-- Header output is omitted. -->
    </tr>
  </thead>
  <tbody>
    <c:forEach var="orderItem" items="${orderItems}">
    <tr>
      <td>
        <!--
          Specify the following attributes.
          name attribute: Specify according to the property name of the form.
          valueObject attribute: Specify the object having the value of the composite key.
          keyNames attribute: Specify the property name used when getting the value of the composite key
                              from the object specified in the valueObejct attribute.
                              Set to the CompositeKey in the order specified here.
          namePrefix attribute: Used when expanding the value of the composite key in request parameters
                                Specify a prefix.
                                It is necessary to specify a value that is different from the name attribute.
        -->
        <n:compositeKeyCheckbox
          name="form.orderItems"
          label=""
          valueObject="${orderItem}"
          keyNames="orderId,productId"
          namePrefix="orderItems" />
      </td>
      <!-- Rest is omitted-->
    </tr>
    </c:forEach>
  </tbody>
</table>

7.19.4.10. Adding a process before submission

Form submission is implemented by assembling the URI for each button/link using JavaScript. The custom tags output this JavaScript function in the global area and output the HTML with the function call configured to the onclick attribute of the button/link.

Signature of the JavaScript function output by the custom tag
/**
 * @param event Event object
 * @param element Event source element (button or link)
 * @return Always false as the event is not propagated
 */
function nablarch_submit(event, element)

An output example is shown below.

JSP
<n:form>
  <!-- Omitted -->
  <n:submit type="submit" uri="login" value="Login" />
</n:form>
HTML
<script type="text/javascript">
<!--
function nablarch_submit(event, element) {
  // Omitted
}
-->
</script>
<form name="nablarch_form1" method="post">
  <!-- JavaScript function for submission control is set to the onclick attribute. -->
  <input type="submit" name="nablarch_form1_1" value="Login"
         onclick="return window.nablarch_submit(event, this);" />
</form>

To add a process before submission, specify the JavaScript function created in the application to the onclick attribute. When the onclick attribute is specified, the custom tag does not specify the JavaScript function for submission. In such cases, it is necessary to call the JavaScript function configured by the custom tag, using the JavaScript created in the application.

Implementation examples

A confirmation dialog box is displayed before submission.

JavaScript
function popUpConfirmation(event, element) {
  if (window.confirm("Will register. Are you sure?")) {
    // Explicitly call the JavaScript function output by the custom tag.
    return nablarch_submit(event, element);
  } else {
    // Cancel
    return false;
  }
}
JSP
<n:submit type="submit" uri="register" value="Register"
          onclick="return popUpConfirmation(event, this);" />

7.19.4.11. Trigger submit on screen operations such as changing the selection in a pull-down

The custom tags use JavaScript for submission control, and operate on the premise that the JavaScript function for submission control is specified in the event handler of a button or a link (onclick attribute). Refer to Adding a process before submission for JavaScript details.

Therefore, to trigger submit on a screen operation such as changing the selection in a pull-down, generate the click event of the corresponding submit button.

The implementation example of submission with change of a pull-down is shown.

Implementation examples
<!-- Call the click function of the corresponding submit button element using the onchange attribute. -->
<n:select name="form.plan"
          listName="plans"
          elementLabelProperty="planName"
          elementValueProperty="planId"
          onchange="window.document.getElementById('register').click(); return false;" />

<n:submit id="register" type="submit" uri="register" value="Register" />

Important

In the above implementation example, JavaScript is written directly in the onchange event handler because it is easy to explain, however, in a live project, it is recommended to dynamically bind the process by using the open source JavaScript library, etc.

7.19.4.16. Preventing double submission

Double submission prevention is used on screens requesting processes that result in a commit to the database. There are two methods for preventing double submission, in the client method and in the server method, which are used in combination.

In the client, if the user double-clicks a button by mistake, or if the user sends a request but clicks the button again because no response is returned from the server, then the request is prevented from being sent more than once.

In the server, the application is prevented from receiving requests that are already processed so that the requests are not processed redundantly by the application, for example, when the screen navigates from the completion screen to the confirmation screen using the back button of the browser and is submitted again.

Important

On the screen that prevents double submission, there are the following concerns if only the client method or the server method is used:

  • If only the client method is used, then there is a risk that the request will be processed redundantly.
  • If only the server method is used, and if a request is sent twice by double-clicking the button, then a double submission error may be returned depending on the processing order in the server, and the process result may not be returned to the user.
Preventing double submission in the client

This is implemented by using JavaScript in the client. When the user submits for the first time, the onclick attribute of the element associated with submit is overwritten, and the subsequent submissions are prevented by not sending the requests to the server . In the case of a button, the disabled attribute is configured so that the button cannot be clicked on the screen.

The following custom tags can be used:

Submit form
submit tag (button of input tag)
button tag (button of button tag)
Submit for download
downloadSubmit tag (button of input tag)
downloadButton tag (button of button tag)

By configuring the allowDoubleSubmission attribute of the above custom tags to false, double submission is prevented only for specific buttons and links.

Implementation examples

Since the register button commits to the database, prevent double submission only for the register button.

<!--
  allowDoubleSubmission attribute: Whether to allow double submission.
                                   Configure to true when allowing double submission; otherwise configure to false.
                                   Default is true.
-->
<n:submit type="button" name="back" value="Back" uri="./back" />
<n:submit type="button" name="register" value="Register" uri="./register"
          allowDoubleSubmission="false" />

Tip

In a client screen where double submission is prevented, if the user clicks the stop button of the browser because there is no response returned from the server following a submission (when there is significant processing load in the server, etc.), the button becomes disabled (inactive due to disabled attribute) and the user cannot submit again. In such cases, the user can continue the process by using a button or a link other than the button used for submission.

Tip

To add a behavior following an occurrence of double submission in the application, refer to Add a behavior when double submission occurs, with a double submission prevention in the client.

Preventing double submission in the server

In the server, a unique token is issued, which is retained in the server (session) and client (hidden tag) and double submission is prevented by matching in the server. This token is valid for one check only.

For preventing double submission in the server, work is required for both, configuration of the token using JSP or action, and checking the token using action.

Configure the token using JSP

The token is configured by specifying useToken attribute of form tag.

Implementation examples
<!--
  useToken attribute: Whether to configure the token.
                      Configure to true when configuring the token; otherwise configure to false.
                      Default is false.
                      When having a common JSP for the input and confirmation screens, default is configured to true for the confirmation screen.
                      Hence, there is no need to configure when having a common JSP for the input and confirmation screens.
-->
<n:form useToken="true">
Configure the token using action
This configuration method is used when a template engine other than JSP is used. Configure the token using UseToken Interceptor. Refer to UseToken Interceptor for the detailed method of use.
Token check
To check the token, use OnDoubleSubmission Interceptor. Refer to OnDoubleSubmission Interceptor for the detailed method of use.
Change the key stored in the session scope

The issued token is saved with the key “/nablarch_session_token” in the session scope. This key can be changed in the component configuration file.

Configuration example
<component name="webConfig" class="nablarch.common.web.WebConfig">
  <!-- Change the key to "sessionToken" -->
  <property name="doubleSubmissionTokenSessionAttributeName" value="sessionToken" />
</component>
Change the key stored in the request scope

The issued token is stored with the key “nablarch_request_token” in the request scope so that it can be used when embedding in a template such as Thymeleaf. This key can be changed in the component configuration file.

Configuration example
<component name="webConfig" class="nablarch.common.web.WebConfig">
  <!-- Change the key to "requestToken" -->
  <property name="doubleSubmissionTokenRequestAttributeName" value="requestToken" />
</component>
Change the name attribute when embedding in hidden

When embedding the token in hidden, the value “nablarch_token” is configured to the name attribute. This name attribute value can be changed in the component configuration file.

Configuration example
<component name="webConfig" class="nablarch.common.web.WebConfig">
  <!-- Change the value configured to the name attribute to "hiddenToken" -->
  <property name="doubleSubmissionTokenParameterName" value="hiddenToken" />
</component>

Important

When preventing double submission in the server, since the token is stored in the session on the server, the token cannot be checked separately for multiple requests from the same user.

Only the transition of screens where double submission is prevented in the server (Registration confirmation → Registration completion and Update confirmation → Update completion) cannot be performed in parallel using multiple windows and multiple tabs by the same user.

When the screen transitions are performed in parallel, the process is continued only for the screen that transitions to the confirmation screen later, and for the screen that transitions to the confirmation screen first, double submission error occurs as the token is old.

Tip

Token is issued by UUIDV4TokenGenerator. Random character strings of 36 characters are generated by UUIDV4TokenGenerator. To change the token issuing process, refer to Change the token issuing process using double submission prevention in the server.

7.19.4.16.1. Storing server-side tokens in the database

In the default implementation, server-side tokens are stored in an HTTP session. Therefore, sticky sessions and session replication must be used when scaling out the application server.

By using an implementation that stores server-side tokens in a database, tokens can be shared among multiple application servers without the need for any particular application server configuration.

See Double submission prevention using the database for details.

../../../_images/db-double-submit.png

7.19.4.17. Common JSP for input screen and confirmation screen

The custom tag for input items can be used to perform output for the confirmation screen using exactly the same JSP written for the input screen.

Use the following custom tags on the common JSP for input screen and confirmation screen.

confirmationPage tag
Used for specifying the path to the JSP of the input screen on the JSP of the confirmation screen, thus enabling the use of a common JSP for the input screen and the confirmation screen.
forInputPage tag
Used for specifying the part to be displayed only on the input screen.
forConfirmationPage tag
Used for specifying the part to be displayed only on the confirmation screen.
ignoreConfirmation tag
Used for specifying the part of the display for the Confirmation screen to be disabled on the confirmation screen. For example, this is used when there is an item that uses checkbox and for this item a check field is to be displayed on the confirmation screen.

Tip

Display control of the input and confirmation screens is performed for the input tags. However, the operation is different for the following tags:

plainHidden tag
This tag is output on both the input and confirmation screens, assuming that the tag is used for passing on the screen transition status etc. across screens.
hiddenStore tag
This tag is output on both the input and confirmation screens since the tag is used for passing on the data stored in Session Store across screens.
Implementation examples

Implementation example of a JSP that outputs the following screen, is shown.

../../../_images/make_common_input_confirm.png

JSP of the Input screen
<n:form>
  <!--
    For input fields, the same JSP is written for the input and confirmation screens.
  -->
  <div>
    <label>Name</label>
    <n:text name="form.name" />
  </div>
  <div>
    <label>Email</label>
    <n:checkbox name="form.useMail" label="Used" offLabel="Not used" />
  </div>
  <div>
    <label>Plan</label>
    <n:select name="form.plan"
              listName="plans"
              elementLabelProperty="planName"
              elementValueProperty="planId" />
  </div>
  <!--
   Since the button display differs between the input and confirmation screens,
   use forInputPage tag and forConfirmationPage tag.
  -->
  <div style="padding: 8px 0;">
    <n:forInputPage>
      <n:submit type="submit" uri="/action/sample/confirm" value="Confirm" />
    </n:forInputPage>
    <n:forConfirmationPage>
      <n:submit type="submit" uri="/action/sample/showNew" value="Back" />
      <n:submit type="submit" uri="/action/sample/register" value="Register" />
    </n:forConfirmationPage>
  </div>
</n:form>
JSP of the confirmation screen
<!--
  Specify the path to the JSP of the input screen.
-->
<n:confirmationPage path="./input.jsp" />

7.19.4.18. Configuring a value to a variable

For values output with the same content to multiple places within a page, such as screen title, maintainability can be improved by referencing a value stored in a variable in the JSP.

The custom tag set tag is provided for configuring a value to a variable.

Implementation examples

Screen title is used by configuring to a variable.

<!-- Specify the variable name for the var attribute. -->
<n:set var="title" value="User information registration" />
<head>
  <!-- Use write tag to output the variable. -->
  <title><n:write name="title" /></title>
</head>
<body>
  <h1><n:write name="title" /></h1>
</body>

Important

Since HTML escape process is not implemented with set tag when output using the variable configured using set tag, write tag should be used for output as shown in the implementation example.

Specify the scope for storing the variable

The scope for storing the variable is specified with the scope attribute. Specify “request” or “page” for the scope attribute.

When the scope attribute is not specified, the variable is configured in the request scope.

Page scope is used when creating UI widgets that are shared throughout the application, and to prevent conflict with other JSP variables.

Set an array or a collection value to a variable

set tag acquires the value as a single value by default when name attribute is specified. In single value acquisition, if the value corresponding to the name attribute is an array or collection, the first element is returned.

In many cases, there is no problem if single value is returned by default, however, when UI widgets that are shared throughout the application are created, sometimes the array or collection may have to be acquired without any changes.

In such cases, by configuring the bySingleValue attribute of set tag to false, it is possible to acquire the array or collection without any change.

7.19.4.19. Using GET request

In some cases, it is necessary to use GET request to support search engines crawlers, etc. and make it possible for users to bookmark URLs.

Custom tags output and use the hidden parameter since they implement functions such as hidden encryption and parameter addition. Therefore, if GET request is performed using form tag, this hidden parameter is added to the URL in addition to the parameters required for the business function. As a result, in addition to unnecessary parameters getting added, the request may not be performed properly due to the limitation on the length of the URL.

If GET is specified in the form tag, the custom tag does not output the hidden parameter. As a result, even if GET request is used in form tag, the above problem does not occur. However, due to the fact that the hidden parameter is not output, the use of the custom tag becomes restricted or the custom tag becomes unusable. Here, the method of handling such custom tags is explained.

Custom tags with usage restriction

Custom tags with usage restriction are shown below:

These custom tags have a function to configure a request parameter for the unchecked state, however, this function cannot be used for GET request since custom tags use hidden encryption for processing.

Handling method
For GET request, determination of the unchecked state when checkboxes are used is done by checking for null value of the said item after validation. Then, it is decided whether the checkboxes are checked or not based on the result of null check and the value for unchecked state is configured for the action.
Unusable custom tags

Unusable custom tags are shown below:

The method of handling and an implementation example of unusable tags is shown below:

hidden tag
Handling method
Use plainHidden tag.
Implementation examples
<%-- For POST --%>
<n:hidden name="test" />

<%-- For GET --%>
<n:plainHidden name="test" />
submit tag
Handling method
Use HTML input tag (type=”submit”). For the action attribute of the form tag, specify the URI corresponding to submit.
Implementation examples
<%-- For POST --%>
<n:form>
  <n:submit type="button" uri="search" value="Search" />
</n:form>

<%-- For GET --%>
<n:form method="GET" action="search">
  <input type="submit" value="Search" />
</n:form>
button tag
Handling method
Use HTML button tag (type=”submit”). For the action attribute of the form tag, specify the URI corresponding to submit.
Implementation examples
<%-- For POST --%>
<n:form>
  <n:button type="submit" uri="search" value="Search" />
</n:form>

<%-- For GET --%>
<n:form method="GET" action="search">
  <button type="submit" value="Search" />
</n:form>
popupSubmit tag
Handling method
Use the HTML input tag (type=”button”) and specify the JavaScript window.open() function for the onclick attribute.
Implementation examples
<%-- For POST --%>
<n:form>
  <n:popupSubmit type="button" value="Search" uri="search"
    popupWindowName="popupWindow" popupOption="width=700,height=500" />
</n:form>

<%-- For GET --%>
<n:form method="GET">
  <input type="button" value="Search"
    onclick="window.open('search', 'popupWindow', 'width=700,height=500')" />
</n:form>
popupButton tag
Handling method
Use the HTML button tag (type=”submit”) and specify the JavaScript window.open() function for the onclick attribute.
Implementation examples
<%-- For POST --%>
<n:form>
  <n:popupButton type="submit" value="Search" uri="search"
    popupWindowName="popupWindow" popupOption="width=700,height=500" />
</n:form>

<%-- For GET --%>
<n:form method="GET">
  <button type="button" value="Search"
    onclick="window.open('search', 'popupWindow', 'width=700,height=500')" />
</n:form>
param tag
Handling method
Write form tag for each button or link for which a parameter is to be added and configure each parameter within the form.
Implementation examples
<%-- For POST --%>
<n:form>
  <n:submit type="button" uri="search" value="Search">
    <n:param paramName="changeParam" value="Test 1"/>
  </n:submit>
  <n:submit type="button" uri="search" value="Search">
    <n:param paramName="changeParam" value="Test 2"/>
  </n:submit>
</n:form>

<%-- For GET --%>
<n:form method="GET" action="search">
  <n:set var="test" value="Test 1" />
  <input type="hidden" name="changeParam" value="<n:write name='test' />" />
  <input type="submit" value="Search" />
</n:form>

<n:form method="GET" action="search">
  <n:set var="test" value="Test 2" />
  <input type="hidden" name="changeParam" value="<n:write name='test' />" />
  <input type="submit" value="Search" />
</n:form>
changeParamName tag
Handling method
The basic method of handling is the same as the popupLink tag. Specify the query string key with the parameter name to changed in the first argument of window.open() within the function that displays a pop-up window.
Implementation examples
<%-- For POST --%>
<n:form>
  <n:text name="test" />
  <n:popupSubmit type="button" value="Search" uri="search"
      popupWindowName="popupWindow" popupOption="width=700,height=500">
    <n:changeParamName inputName="test" paramName="changeParam" />
  </n:popupSubmit>
</n:form>

<%-- For GET --%>
<input type="text" name="test" id="test" />
<input type="button" value="Search" onclick="openTest();" />
<n:script type="text/javascript">
  var openTest = function() {
    var test = document.getElementById('test').value;
    window.open('search?changeParam=' + test,
                'popupWindow', 'width=700,height=500');
  }
</n:script>

7.19.4.20. Output of a value

Use write tag to output a value.

Access the object set in the request scope for the action, by specifying the name attribute. Refer to Rules to access input/output data for the method of specifying the name attribute.

Implementation examples
Action
// Configure an object in the request scope with the name "person".
Person person = new Person();
person.setPersonName("Name");
context.setRequestScopedVar("person", person);
JSP
<!-- Access the personName property of the object by specifying the name attribute. -->
<n:write name="person.personName" />

7.19.4.21. Output of a value without HTML escape

Use write tag to output a value set in the action etc. on the page. However, to directly output the HTML tag in the variable without performing HTML escape, use the following custom tags.

These custom tags are supposed to be used in a system that allows system administrators to configure maintenance information, and only for specific screens and display areas.

prettyPrint tag

Custom tags that output HTML text formatting tags such as <b> and <del> without performing escape. For usable HTML tags and attributes, arbitrary tags can be configured in safeTags property / safeAttributes property in Configure custom tags. Refer to the link for tags and attributes that can be used by default.

Important

This tag is not recommended due to the following problems:

  • Not only the usable tags but also the attributes used with those tags must be configured in CustomTagConfig. For example, to make a tag usable, it is not sufficient to add a tag to CustomTagConfig#safeTags>, but all the attributes such as href that are used with a tag in CustomTagConfig#safeAttributes must be defined.
  • Whether a character string that is input uses only the tags and attributes that are configured in CustomTagConfig is checked, however whether the correct HTML has been output is not checked.

Therefore, to implement a function that outputs a character string that the user has formatted according to their choice on the screen, the implementation must be according to the PJ requirements by referring to the following procedure.

  1. Using the HTML parser of OSS to parse the value input and validating that it contains no unusable HTML tags
  2. Output to screen using rawWrite tag

In addition, for simple formatting, there is a method in which the user inputs using Markdown, and the Markdown is converted to HTML using the JavaScript library of OSS.

Important

If the contents of a variable output by prettyPrint tag can be configured arbitrarily by an unspecified user, it may result in a vulnerability. Therefore, care must be taken with the selection when configuring usable HTML tags and attributes. For example, <script> tag and onclick attribute must not be made usable as doing so directly leads to cross-site scripting (XSS) vulnerability.

rawWrite tag

Custom tags that output the contents of a character string in a variable as it is without performing escape.

Important

If the contents of a variable output by rawWrite tag can be configured arbitrarily by an unspecified user, it will directly lead to cross-site scripting (XSS) vulnerability. Therefore, careful consideration is required when using rawWrite tag.

7.19.4.22. Output of values after formatting

The custom tags provide a function to format and output values such as date and amount in an easy-to-see format.

There are two methods of formatting, namely, the method that uses Formatter and the method that uses valueFormat attribute. The method of formatting that uses Formatter is recommended for the following reasons:

  • In the method of formatting that uses Formatter, the configuration can be consolidated at one place since this method shares the components that are used for format processing in other output functions such as file output and messaging. Also, there are no limitations on the tags that can be used.
  • The method of formatting that uses valueFormat attribute is implemented independently by the custom tags and can be used only with the custom tags. Hence, the separate configuration is required for formatting in other output functions. Due to this, the configuration related to formatting exists at multiple places and the management becomes complicated. In addition, valueFormat attribute can be used only with write tag and text tag.
Formatter

When using Formatter, use n:formatByDefault or n:format in the EL expression and configure the formatted character string for the value attribute.

EL expression is a writing method that makes it possible to output an operation result using a simple syntax in JSP. The evaluation result is output as it is using ${<Expression to be evaluated>} syntax.

By using n:formatByDefault and n:format within the EL expression, the value can be formatted by calling FormatterUtil of Formatter.

Implementation examples
<!-- When formatted using the default formatter pattern
  The name of the formatter used is specified in the first argument
  The value to be formatted is specified in the second argument
  For the value attribute, n:formatByDefault call is written using EL expression-->
<n:write value="${n:formatByDefault('dateTime', project.StartDate)}" />

<!-- When formatted using the specified pattern
  The name of the formatter used is specified in the first argument
  The value to be formatted is specified in the second argument
  The formatting pattern is specified in the third argument
  For the value attribute, n:format call in written using EL expression -->
<n:text name="project.StartDate" value="${n:format('dateTime', project.StartDate, 'yyyy年MM月dd日')}" />

Important

Request parameters cannot be referenced in EL expression. Therefore, when checking the value input by the web application user using Bean Validation, the following must be configured:

Request parameters are to be obtained from the request scope even when there is a validation error

If the above configuration cannot be used, then the value must be acquiredfrom the request parameter using n:set and output after setting in the page scope.

Implementation examples

<n:set var="projectEndDate" name="form.projectEndDate" scope="page" />
<n:text name="form.projectEndDate" nameAlias="form.date"
  value="${n:formatByDefault('dateTime', projectEndDate)}"
  cssClass="form-control datepicker" errorCss="input-error" />
valueFormat attribute

The formatted value is output by specifying valueFormat attribute.When valueFormat attribute is not specified, the value is output without formatting. The only usable tags are write tag and text tag.

The format is specified using data type{pattern} format. The data types provided by default in the custom tags are shown below:

yyyymmdd

Date format.

For the value, specify a character string in yyyyMMdd format or the pattern format. For the pattern, specify the syntax specified by SimpleDateFormat. For pattern characters, only y (year), M (month) and d (date of a month) can be specified. When the pattern character string is omitted, default pattern configured in the Configure custom tags (yyyymmddPattern property) is used.

Also, locale of the format can be specified using the delimiting character | after the pattern. When locale is not specified explicitly, the language in ThreadContext is used. When ThreadContext is not configured, default locale value of the system is used.

Implementation examples
# Default pattern and the locale configured in the thread context are used.
valueFormat="yyyymmdd"

# Explicitly specified pattern and the locale configured in the thread context are used.
valueFormat="yyyymmdd{yyyy/MM/dd}"

# When using default pattern and specifying only the locale.
valueFormat="yyyymmdd{|ja}"

# When explicitly specifying both the pattern and the locale.
valueFormat="yyyymmdd{yyyyMMd|ja}"

Important

When valueFormat attribute of text tag is specified, the formatted value is output also on the input screen. When the input date is acquired by action, window scope and date converter provided by the Nablarch original validation are used. text tag, window scope and date converter work together to perform value conversion and validation using the pattern specified for the valueFormat attribute.

Further, Bean Validation is not supported for the valueFormat attribute of text tag.

Important

When window scope is not used, validation error occurs as the value of the valueFormat attribute is not sent to the server even if valueFormat attribute of text tag is specified. In that case, input value can be checked by specifying the allowFormat attribute of YYYYMMDD annotation.

yyyymm

Year and month format.

Specify a character string in yyyyMM format or pattern format for the value. Method of use is the same as yyyymmdd (date).

dateTime

Date and time format.

Specify Date type for the value. For the pattern, specify the syntax specified by SimpleDateFormat. The date and time according to the language and time zone configured in ThreadContext are output by default. The locale and time zone can be specified explicitly by using the delimiting character | after the pattern character string.

By using Configure custom tags (dateTimePattern property, patternSeparator property), it is possible to configure the pattern default value and change the delimiting character |.

Implementation examples
# When using default patten and the locale and time zone configured in ThreadContext.
valueFormat="dateTime"

# When using default pattern and specifying only the locale and time zone.
valueFormat="dateTime{|ja|Asia/Tokyo}"

# When using default pattern and specifying only the time zone.
valueFormat="dateTime{||Asia/Tokyo}"

# When specifying the pattern, locale, as well as time zone.
valueFormat="dateTime{yyyyMMMd(E) a hh:mm|ja|America/New_York}}"

# When specifying the pattern and time zone.
valueFormat="dateTime{yy/MM/dd HH:mm:ss||Asia/Tokyo}"
decimal

Decimal format

Specify the Number type or a character string of numerals for the value. Character strings are formatted after removing the thousands separator (commas in 1,000,000). For the pattern, specify the syntax specified by DecimalFormat.

By default, the value is output in the language-specific format using the language configured in ThreadContext. By directly specifying the language, the value can be output in the format corresponding to the specified language. The language is specified by adding a language after the delimiting character | at the end of the pattern.

The delimiting character | can be changed using the Configure custom tags (patternSeparator property).

Implementation examples
# When using the language configured in ThreadContext and specifying only the pattern.
valueFormat="decimal{###,###,###.000}"

# When specifying the pattern and the language
valueFormat="decimal{###,###,###.000|ja}"

Important

Since only formatting of values is performed in this function, the configuration for the rounding operation is not performed. (default of DecimalFormat is used.)

To perform the rounding process, it should be performed in the application, and formatting should be performed using this function.

Important

When the valueFormat attribute of text tag is specified, the formatted value is output also on the input screen. To acquire the input numeric value by action, use the numeric converter ( BigDecimalConvertor, IntegerConvertor and LongConvertor ). text tag and numeric converter work together to perform value conversion and validation corresponding to the language specified for the valueFormat attribute.

Further, Bean Validation is not supported for the valueFormat attribute of text tag.

Tip

When specifying the thousands separator and decimal point in the pattern, always use a comma for the thousands separator and a dot for the decimal point, regardless of the language.

# For es (Spanish), the thousands separator is formatted to a dot and the decimal point is formatted to a comma.
# In pattern specification, always specify a comma as the thousands delimiter and a dot as the decimal point.
valueFormat="decimal{###,###,###.000|es}"

# The following will throw a runtime exception due to an invalid pattern specification.
valueFormat="decimal{###.###.###,000|es}"

7.19.4.23. Performing error display

The error display provides the following functions:

Tip

In the custom tags used for error display, error messages are output by acquiring ApplicationException from the request scope. ApplicationException is configured in the request scope using OnError Interceptor.

List of error messages

Use errors tag to display error messages in a list format at the top of the screen.

Display all error messages

Implementation examples
<!-- Specify “all” for the filter attribute. -->
<n:errors filter="all" errorCss="alert alert-danger" />
Output result
../../../_images/errors_all.png
Display only the error messages not corresponding to the input items

Implementation examples
Action
// ApplicationException is thrown by correlation validation with the database, etc.
throw new ApplicationException(
  MessageUtil.createMessage(MessageLevel.ERROR, "errors.duplicateName"));
JSP
<!-- Specify "global" for the filter attribute. -->
<n:errors filter="global" errorCss="alert alert-danger" />
Output result
../../../_images/errors_global.png
Individual display of error messages

Use error tag to display an error message for each input item.

Implementation examples
<div>
  <label>Name</label>
  <n:text name="form.userName" />
  <!-- Specify the same name as the input item for the name attribute. -->
  <n:error name="form.userName" messageFormat="span" errorCss="alert alert-danger" />
</div>
Output result
../../../_images/error.png

Use error tag also for displaying Performing Correlation Validation error messages near specific items.

Implementation examples
Form
// Method for performing correlation validation
// Error messages are configured with this property name.
@AssertTrue(message = "The password does not match.")
public boolean isComparePassword() {
    return Objects.equals(password, confirmPassword);
}
JSP
<div>
  <label>Password</label>
  <n:password name="form.password" nameAlias="form.comparePassword" />
  <n:error name="form.password" messageFormat="span" errorCss="alert alert-danger" />
  <!--
    Specify the property name specified in correlation validation for the name attribute.
  -->
  <n:error name="form.comparePassword" messageFormat="span" errorCss="alert alert-danger" />
</div>
<div>
  <label>Password (for confirmation)</label>
  <n:password name="form.confirmPassword" nameAlias="form.comparePassword" />
  <n:error name="form.confirmPassword" messageFormat="span" errorCss="alert alert-danger" />
</div>
Output result
../../../_images/error_correlation_validation.png
Highlight display of input items

In the custom tag for input items, add the CSS class name (default is “nablarch_error”) for the original value of the class attribute of the input item that caused the error.

By specifying the style for this class name using CSS, the input item for which an error has occurred is highlighted.

Further, multiple input items can be linked by specifying the nameAlias attribute in the custom tags for input items, and multiple input items can be highlighted when an error occurs during Performing Correlation Validation.

Implementation examples
CSS
/* Specify background color of the input item for which error occurs. */
input.nablarch_error,select.nablarch_error {
  background-color: #FFFFB3;
}
JSP
<div>
  <label>Password</label>
  <!-- Specify correlation validation property name for the nameAlias attribute. -->
  <n:password name="form.password" nameAlias="form.comparePassword" />
  <n:error name="form.password" messageFormat="span" errorCss="alert alert-danger" />
  <n:error name="form.comparePassword" messageFormat="span" errorCss="alert alert-danger" />
</div>
<div>
  <label>Password (for confirmation)</label>
  <!-- Specify correlation validation property name for the nameAlias attribute. -->
  <n:password name="form.confirmPassword" nameAlias="form.comparePassword" />
  <n:error name="form.confirmPassword" messageFormat="span" errorCss="alert alert-danger" />
</div>
Output result
../../../_images/error_css.png

7.19.4.24. Display code values

There are custom tags dedicated to code values that output selection items and display items for code values acquired from Code Management.

An implementation example of code tag and codeSelect tag is shown.

Implementation examples

The Code Management table is as follows:

Code pattern table
ID VALUE PATTERN1 PATTERN2
GENDER MALE 1 1
GENDER FEMALE 1 1
GENDER OTHER 1 0
Code name table
ID VALUE LANG SORT_ORDER NAME SHORT_NAME
GENDER MALE en 1 Male M
GENDER FEMALE en 2 Female F
GENDER OTHER en 3 Other O
code tag (code values)
JSP
<!--
  Output of code values is controlled by specifying the following attributes.
  codeId attribute: Code ID.
  pattern attribute: Column name of the pattern used.
                     Default is not specified.
  optionColumnName attribute: Column name of option name to acquire.
  labelPattern attribute: Pattern to format the label.
                          The following placeholder can be used:
                          $NAME$: Code name corresponding to code value
                          $SHORTNAME$: Abbreviation of code corresponding to code value
                          $OPTIONALNAME$: Option name of code corresponding to code value
                                          When using this placeholder,
                                          the optionColumnName attribute is required.
                          $VALUE$: Code value
                          Default is $NAME$.
-->
<n:code name="user.gender"
        codeId="GENDER" pattern="PATTERN1"
        labelPattern="$VALUE$:$NAME$($SHORTNAME$)"
        listFormat="div" />
Output HTML
<!--
  If "user.gender" is "FEMALE",
  it is output with div tag as div is specified in listFormat attribute.
-->
<div>FEMALE:Female(F)</div>
codeSelect tag (pull-down for code values)
JSP
<!--
  Specification of attribute is the same as select tag.
-->
<n:codeSelect name="form.gender"
              codeId="GENDER" pattern="PATTERN2"
              labelPattern="$VALUE$-$SHORTNAME$"
              listFormat="div" />
Output HTML
<!-- If "form.gender" is "FEMALE" -->

<!-- Input screen -->
<select name="form.gender">
  <option value="MALE">MALE-M</option>
  <option value="FEMALE" selected="selected">FEMALE-F</option>
</select>

<!-- Confirm screen -->
<div>FEMALE-F</div>

Important

In custom tags, it is not possible to acquire code values according to the specified language. In custom tags, an API is used in which the locale of CodeUtil is not specified. To acquire a code value using the language specification, use CodeUtil in the action.

7.19.4.25. Output of messages

There are custom tags that output messages acquired using Message Management.

When multiple languagesare supported by one JSP file in the application that performs internationalization, the text on the screen can be switched according to the language selected by the user, by using message tag.

Implementation examples
<!-- Specify the message ID for the messageId attribute. -->
<n:message messageId="page.not.found" />

<!--
  To specify option
-->

<!-- Specify the var attribute to acquire the text for embedding. -->
<n:message var="title" messageId="title.user.register" />
<n:message var="appName" messageId="title.app" />

<!-- Configure the text for embedding for the option attribute. -->
<n:message messageId="title.template" option0="${title}" option1="${appName}" />

<!--
  To change the language only for some messages within the screen
-->

<!-- Specify a language for the language attribute. -->
<n:message messageId="page.not.found" language="ja" />

<!--
  If HTML escape is not required
-->

<!-- Specify false in the secure attribute. -->
<n:message messageId="page.not.found" htmlEscape="false" />

7.19.4.26. Switch resource path for each language

The custom tags that handle resource path have a function to dynamically switch the resource path based on the language configuration. The following custom tags support resource path switching for each language.

In these custom tags, switching is performed by acquiring the resource path for each language using the subclass of ResourcePathRule. Refer to Switching the content path for each language for the subclass provided by default.

Tip

include tag is provided to associate the dynamic include of JSP with resource path switching for each language. Use includeParam tag to specify the parameter to be added at the time of dynamic include.

<!-- For the path attribute, specify the resource path to be included. -->
<n:include path="/app_header.jsp">
    <!--
      Specify parameter name for the paramName attribute and value for the value attribute.
      Specify the name attribute when using the value configured in the scope.
      Specify either name attribute or value attribute.
    -->
    <n:includeParam paramName="title" value="User information details" />
</n:include>

7.19.4.27. Prevent browser caching

By preventing browser caching, it is possible to prevent the previous screen from being displayed when the back button of the browser is clicked. As a result, in an environment where multiple users use the same terminal, leakage of personal information and confidential information by browser operation is prevented.

noCache tag is used to prevent browser caching. Since the back button of the browser redisplays the cached screen during screen display, use noCache tag in the JSP of the screen that should not be cached.

Implementation examples
<!-- Specify a noCache tag within the head tag. -->
<head>
  <n:noCache/>
  <!-- Rest is omitted. -->
</head>

When noCache tag is specified, the following response header and HTML are returned to the browser.

Response header
Expires Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma no-cache
HTML
<head>
  <meta http-equiv="pragma" content="no-cache">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="expires" content="0">
</head>

Important

Since the noCache tag cannot be specified in the JSP included in include tag (<jsp: include>), it must be specified in the forwarded JSP. However, when preventing browser caching for the entire system, create a handler in the project and configure it uniformly so that implementation is not omitted in any JSP. In the handler, configure the contents of the above response header example in the response header.

Tip

According to the HTTP specification, only the response header should be specified, but a meta tag is also specified for older browsers that do not conform to this specification.

Tip

Prevention of browser caching is not enabled for the communication on the following browsers where HTTP/1.0 and SSL (https) are not used. Therefore, screens that prevent browser caching must be designed to use SSL communication.

Browsers with problems: IE6, IE7, IE8

7.19.4.28. Not allowing the cache in the client to be referenced when static content is changed

When caching is enabled in the client (browser), even if the static content placed on the server is replaced, the cached old content may be displayed in the client instead of the latest content.

To avoid this problem, a function is provided in which a version is appended to the URI of the static content specified in the href attribute and src attribute of the following custom tags, using parameters.

As a result, the latest static content can be referenced instead of the cache in the client when the static content is replaced.

The version of the static content that is added using parameters is configured in the configuration file (properties file). This function is disabled if the version of the static content is not configured in the configuration file.

The version of the static content is specified with the key name static_content_version.

Configuration example
# Version of the static content
static_content_version=1.0

Important

This function is deprecated because of the following reasons:

  • Since only one version of the static content can be defined in the application using static_content_version, if the value of static_content_version is changed, all static content (including unchanged static content) in the application references the latest static content instead of the cache.

The file name of the static content should be changed instead of using this function so that the cache is not referenced when the static content is changed.

7.19.4.29. Specify Boolean attributes

Boolean attributes defined in Custom Tags can be controlled by specifying true / false for the value to output or not.

An example implementation of disabled is shown below.

JSP
<!-- Specify true for Boolean attribute -->
<n:text name="form.userId" disabled="true" />
Output HTML
<!-- Boolean attributes will be output -->
<input type="text" name="form.userId" disabled="disabled" />
JSP
<!-- Specify false for Boolean attribute -->
<n:text name="form.userId" disabled="false" />
Output HTML
<!-- Boolean attributes will not be output -->
<input type="text" name="form.userId" />

7.19.4.30. Specify any attributes

Dynamic attributes are handled in custom tags using the javax.servlet.jsp.tagext.DynamicAttributes interface. This makes it possible to output arbitrary attributes including attributes added in HTML5 with custom tags. For tags that output HTML, dynamic attributes can be used.

7.19.4.30.1. Handling of Boolean attributes

As with the Boolean attributes defined in Custom Tags, Dynamic attributes regarded as Boolean attributes can be controlled by specifying true / false for the value to output or not. By default, the following attributes are regarded as Boolean attributes.

  • async
  • autofocus
  • checked
  • disabled
  • formnovalidate
  • hidden
  • ismap
  • itemscope
  • multiple
  • nomodule
  • novalidate
  • readonly
  • required
  • reversed
  • selected

Dynamic attributes regarded as Boolean attributes can be modified. To do so, configure the list of Boolean attributes to dynamicBooleanAttributes property of CustomTagConfig .

7.19.5. Expansion example

7.19.5.1. Adding formatter

For the method of adding a formatter when using Formatter, refer to the section on adding a formatter of Formatter.

When using the valueFormat attribute, formatting is performed by the class that implements the ValueFormatter interface. The format can be changed by adding the implementation class to the component definition.

To add to the component definition, specify the class that implements ValueFormatter as the value, and the data type name as the key in the Map type.

A configuration example for the default format supported by the framework is shown below.

The formatter map is added to the component definition with the name valueFormatters.

<map name="valueFormatters">
  <entry key="yyyymmdd">
    <value-component class="nablarch.common.web.tag.YYYYMMDDFormatter" />
  </entry>
  <entry key="yyyymm">
    <value-component class="nablarch.common.web.tag.YYYYMMFormatter" />
  </entry>
  <entry key="dateTime">
    <value-component class="nablarch.common.web.tag.DateTimeFormatter" />
  </entry>
  <entry key="decimal">
    <value-component class="nablarch.common.web.tag.DecimalFormatter" />
  </entry>
</map>

7.19.5.3. Add a behavior when double submission occurs, with a double submission prevention in the client

For adding a behavior during occurrence of double submission in the application, using double submission prevention on the client side, implement the callback function in JavaScript.

The JavaScript function of the framework calls a callback function if the callback function exists, when the second or subsequent submission request occurs. The signature of the callback function is shown below:

/**
 * @param element Target element (button or link) for which double submission was performed
 */
function nablarch_handleDoubleSubmission(element) {
  // Describe the process here.
}

7.19.5.4. Change the token issuing process using double submission prevention in the server

To change the token issuing process using double submission prevention in the server, implement the TokenGenerator interface. Add the implementation class to the component definition with the name tokenGenerator.

7.19.6. Custom tag rules

7.19.6.1. Naming rules

In the custom tags, the prefix nablarch_ is used for the names prescribed by the custom tags, such as CSS class name and JavaScript function name, to avoid duplication with individual applications. Therefore, names starting with nablarch_ should not be used in individual applications.

The naming rules are applicable to the following:

  • HTML attribute value
  • CSS class name
  • JavaScript function name and global variable name
  • Page scope, request scope and session scope variable names

7.19.6.2. Rules to access input/output data

The custom tags (such as text tag and write tag) that output the input items and output items, access the data to be output based on the value of the name attribute.

Specify the following for the name attribute according to the type of object:

  • When accessing the object/map properties, specify the dot separator.
  • When accessing the list/array elements, specify square brackets (index in parentheses).

The search order is as follows, and the first value is used. If the value cannot be acquired, an empty string is output.

  1. Page scope
  2. Request scope
  3. Request parameters
  4. Session scope
Object implementation example

Action
// Configure the object in the request scope.
PersonForm form = new PersonForm();
form.setPersonName("Name");
context.setRequestScopedVar("form", form);
return new HttpResponse("/WEB-INF/view/sample/accessRuleObject.jsp");
JSP
<!-- Use the dot delimiter. -->
<n:text name="form.personName" />
List implementation example

Action
// Configure the object with list in the request scope.
PersonsForm form = new PersonsForm();
List<Person> persons = UniversalDao.findAll(Person.class);
form.setPersons(persons);
context.setRequestScopedVar("form", form);
JSP
<!-- Loop to acquire to the index. -->
<c:forEach items="${form.persons}" varStatus="status">
  <!--
    Access the elements using square brackets.
    Access the element values using dots.
  -->
  <n:text name="form.persons[${status.index}].personName" />
</c:forEach>

Tip

The request parameter is included in the search target to restore the input value when the input form is redisplayed with the custom tag for input items.

Since this behavior differs between Nablarch custom tags and JSTL (c: forEach, c: out, etc.), take adequate care during implementation. Since the JSTL tag cannot access the value of the request parameter, when using the JSTL tag, it is necessary to explicitly configured the value in the request scope for the action.

Tip

The request scope is searched before the request parameter is accessed so that the input value can be changed when the input form is redisplayed.

A common example is when a user wants to return a radio button to the unselected state when redisplaying the input form and guarantee that the system has registered the radio button selected by the user.

In such cases, if an empty string is configured in the request scope for the action, the radio button can be returned to the unselected state.

7.19.6.3. URI specification method

In the custom tags, use one of the following methods to specify the URI

Absolute URL

Path starting with http/https

<n:a href="https://github.com/coastland">coastland</n:a>

Used when a different URI is specified for the application and host, such as by linkage with other systems. The custom tags use the specified path without any change.

Relative path from the context

Path starting with a / (slash)

<n:submit type="submit" uri="/action/person/register" value="Register" />

Used when specifying the path within the application. The custom tags use the specified path by adding the context path in the beginning.

Relative path from the current path

Path that does not start with a / (slash) (except absolute URL)

<n:submit type="submit" uri="login" value="Login" />

Used when specifying the path within the application. The custom tags use the specified path without any change.

Switching between https and http

When relative path from the context is specified, switching between https and http can be performed for a URI by specifying the secure attribute of the custom tag.

When the secure attribute is specified, a URI is assembled using the configured values of the custom tags (port number for http, port number for https and host) and the context path. Therefore, in applications that use the secure attribute, specify port property / securePort property / host property with Configure custom tags.

Tip

The secure attribute is used only for buttons and links that switch the protocol of the transition destination. Do not specify the secure attribute when the protocol of the transition destination is the same (http→http、https→https).

Implementation examples

An example of using the secure attribute is shown.

Configuration values of custom tags
Port number for http:
 8080
Port number for https:
 443
host:sample.co.jp
Switch from http to https

<!-- Specify true in secure attribute. -->
<n:submit type="button" name="login" value="Login" uri="/action/login" secure="true" />
# URI to be assembled
https://sample.co.jp:443/<Context path>/action/login
Switch from https to http

<!-- Specify false in secure attribute. -->
<n:submitLink name="logout" uri="/action/logout" secure="false">Logout</n:submitLink>
# URI to be assembled
https://sample.co.jp:8080/<Context path>/action/logout

# If the port number for http in the custom tag configuration is not specified
# Port number is not output.
https://sample.co.jp/<Context>/action/logout

7.19.6.4. HTML escape, line feed and half width space conversion

HTML escape

In the custom tags, as a general rule, HTML escape is performed for all HTML attributes during output. The content that is converted is shown below:

Conversion during HTML escape
&&amp;
<&lt;
>&gt;
&#034;
&#039;

Important

Since the EL expression does not perform HTML escape processing, the values should not be output using the EL expression. Use custom tags such as write tag to output the values.

However, there is no problem if the EL expression is used at places where there is no direct output, such as when configuring an object for JSTL forEach tag or a custom tag attribute.

Line feed and half-width space conversion

When input data is output on the Confirmation screen, etc., in addition to HTML escape, line feed and half-width space are converted. The content that is converted is shown below:

Contents of line feed and half-width space conversion
Line feed code(\n、\r、\r\n)<br />
Half-width&nbsp;