add_action('wp_footer', function () { echo ''; }, 99);
add_action('wp_footer', function () { echo ''; }, 99);
The post Save Bitmap Image in BlackBerry Java appeared first on javatechig.com.
]]>This post explains how to save a bitmap image file to the filesystem in BlackBerry Java applications. The example uses BlackBerry’s native APIs to encode a Bitmap object into PNG format and write it to device storage. This approach is common when building legacy BlackBerry Java apps requiring image persistence.
BlackBerry Java uses classes such as PNGEncodedImage, FileConnection, and the system graphics APIs. It’s important to handle file I/O and encoding properly to avoid errors and ensure compatibility across devices.
Bitmap represents raw pixel data.PNGEncodedImage encodes a Bitmap into PNG format (lossless compression).
PNGEncodedImage.encode().javax.microedition.io.file.FileConnection (JSR-75) to access the filesystem.The following example shows how to save a bitmap as a PNG file on the BlackBerry filesystem (such as SDCard or device storage).
Bitmap object.PNGEncodedImage.FileConnection.import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.PNGEncodedImage;
public class ImageSaver {
public static boolean saveBitmapToFile(String path, Bitmap bitmap) {
FileConnection fileConn = null;
OutputStream out = null;
try {
// Open or create the file
fileConn = (FileConnection) Connector.open(path, Connector.READ_WRITE);
if (!fileConn.exists()) {
fileConn.create();
}
// Encode bitmap to PNG bytes
PNGEncodedImage pngImage = PNGEncodedImage.encode(bitmap);
byte[] imageData = pngImage.getData();
// Open output stream and write data
out = fileConn.openOutputStream();
out.write(imageData);
out.flush();
return true;
} catch (Exception e) {
System.out.println("Error saving bitmap: " + e.toString());
return false;
} finally {
try {
if (out != null) out.close();
if (fileConn != null) fileConn.close();
} catch (Exception ignored) {}
}
}
}
Bitmap myBitmap = Bitmap.getBitmapResource("example.png");
String savePath = "file:///SDCard/BlackBerry/pictures/saved_image.png";
boolean success = ImageSaver.saveBitmapToFile(savePath, myBitmap);
if (success) {
System.out.println("Image saved to " + savePath);
}
Common storage paths on BlackBerry devices:
file:///store/home/user/…file:///SDCard/BlackBerry/pictures/…Always confirm the target path exists and the application has appropriate permissions.
try/finally to ensure streams and connections are closed.bitmap is not null before encoding.This document shows how to encode and save a Bitmap as a PNG image file on legacy BlackBerry devices using Java APIs such as PNGEncodedImage and FileConnection. While the BlackBerry platform is legacy, understanding this pattern remains useful when maintaining enterprise applications built on BlackBerry Java.
The post Save Bitmap Image in BlackBerry Java appeared first on javatechig.com.
]]>The post Insertion Sort in Java – Example & Step‑by‑Step Guide appeared first on javatechig.com.
]]>This updated guide on javatechig.com explains how insertion sort works, provides clear Java code examples, analyzes time and space complexity, and discusses best practices for real‑world usage.
Insertion sort iterates through the array and constructs a sorted portion on the left side. For each element, it finds the correct position in the sorted part by shifting larger elements to the right.
Key characteristics:
| Scenario | Time Complexity |
|---|---|
| Best Case (sorted) | O(n) |
| Average Case | O(n²) |
| Worst Case (reverse) | O(n²) |
| Space Complexity | O(1) |
Insertion sort performs well on small datasets or partially sorted collections due to low overhead and simple inner loops.
public static void insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
public static void main(String[] args) {
int[] data = {9, 5, 1, 4, 3};
insertionSort(data);
System.out.println("Sorted Array:");
for (int num : data) {
System.out.print(num + " ");
}
}
This standard implementation shifts elements greater than the key to the right, then places the key in its correct spot.
1 (first unsorted element).You can generalize insertion sort for any type that implements Comparable.
public static > void insertionSort(T[] array) {
for (int i = 1; i < array.length; i++) {
T key = array[i];
int j = i - 1;
while (j >= 0 && array[j].compareTo(key) > 0) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
}
This version works for String[], Integer[], or custom object arrays as long as they implement Comparable.
Although Java provides Collections.sort() and List.sort(), understanding insertion sort helps when:
Insertion sort is useful when:
Avoid insertion sort for:
In such cases, prefer merge sort, quick sort, or TimSort used by Java’s built‑in sorting.
Without shifting, the algorithm doesn’t rearrange elements properly.
Generic implementation requires Comparable — always use the constraint to ensure robust sorting.
The post Insertion Sort in Java – Example & Step‑by‑Step Guide appeared first on javatechig.com.
]]>The post Searching Arrays and Collections in Java – Methods and Examples appeared first on javatechig.com.
]]>This tutorial covers common techniques for searching in both arrays and collections, including primitive arrays, object arrays, List, Set, and advanced search patterns.
Java’s Arrays utility class provides methods for searching arrays.
Arrays.binarySearch() (Sorted Arrays)The Arrays.binarySearch() method performs a binary search on a sorted array.
int[] numbers = {10, 20, 30, 40, 50};
int index = Arrays.binarySearch(numbers, 30);
System.out.println("Index: " + index);
Key Points:
binarySearch.int missing = Arrays.binarySearch(numbers, 25);
System.out.println(missing); // Negative value
This negative value indicates where the key would be inserted.
For an array of objects such as String[]:
String[] names = {"Alice", "Bob", "Charlie"};
int idx = Arrays.binarySearch(names, "Bob");
The array must be sorted lexicographically for correct results.
If the array is not sorted or you need a custom condition, use a simple loop:
String[] names = {"Alice","Bob","Charlie"};
String target = "Charlie";
int index = -1;
for (int i = 0; i < names.length; i++) {
if (names[i].equals(target)) {
index = i;
break;
}
}
System.out.println("Found at index: " + index);
This pattern works for any array type and custom matching.
Java Collection types (List, Set, Map) offer flexible search operations.
List.indexOf()List list = Arrays.asList("Java", "Python", "C++");
int pos = list.indexOf("Python");
System.out.println("Position: " + pos);
indexOf() returns the first matching index or -1 if not found.
List.contains()boolean found = list.contains("Java");
System.out.println(found); // true
contains() tests for existence without index.
Streams provide expressive and flexible search patterns:
List list = Arrays.asList("Java", "Python", "C++");
// Find first match
Optional result = list.stream()
.filter(s -> s.startsWith("P"))
.findFirst();
result.ifPresent(System.out::println);
This allows arbitrary conditions without manual loops.
Sets don’t preserve order and don’t have indexes, but you can check existence:
Set set = new HashSet<>(list);
boolean exists = set.contains("C++");
Use streams when you need more complex filters:
boolean match = set.stream().anyMatch(s -> s.endsWith("++"));
Maps store key-value pairs.
Map map = new HashMap<>();
map.put("Alice", 30);
map.put("Bob", 25);
boolean hasKey = map.containsKey("Bob");
boolean hasValue = map.containsValue(30);
To find entries by condition:
map.entrySet().stream()
.filter(e -> e.getValue() > 28)
.forEach(System.out::println);
Primitive arrays like int[] or double[] require slightly different handling.
As shown earlier:
double[] values = {1.2, 3.4, 5.6};
int pos = Arrays.binarySearch(values, 3.4);
Always ensure the array is sorted.
int[] nums = {5, 9, 1, 7};
int target = 9;
int idx = -1;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == target) {
idx = i;
break;
}
}
Manual loops are simple and effective for small arrays.
When searching sorted arrays of custom objects:
Person[] people = {...};
Arrays.sort(people, Comparator.comparing(Person::getName));
int index = Arrays.binarySearch(
people,
new Person("John", 0),
Comparator.comparing(Person::getName)
);
This allows binary search on custom fields.
Using streams to collect all matches:
List allMatches = list.stream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
This returns a new list of found elements.
Arrays.binarySearch() has O(log n) complexity but requires a sorted array.loop) has O(n) complexity, suitable for small or unsorted inputs.Choose technique based on performance needs and data size.
From real enterprise experience:
These practices help build efficient, maintainable search logic throughout your applications.
Searching arrays and collections in Java can be done using:
Arrays.binarySearch() for sorted arraysList.indexOf() and contains() for collectionsEach method has use cases and performance characteristics that you can choose based on your requirements.
The post Searching Arrays and Collections in Java – Methods and Examples appeared first on javatechig.com.
]]>The post Convert Array to List in Java – Methods and Examples appeared first on javatechig.com.
]]>List is a common requirement in Java development — whether you are adapting legacy code, collecting API results, or working with collections APIs that expect List types. Java offers multiple ways to perform this conversion depending on the data type, desired mutability, and target use case.
This tutorial explains all major approaches, their behavior, and best practices with clear code examples.
Arrays.asList()The simplest way to convert an array to a List is the Arrays.asList() method from java.util.Arrays.
String[] array = {"Java", "Python", "C++"};
List list = Arrays.asList(array);
System.out.println(list);
Key Characteristics:
UnsupportedOperationException)Use this when you need a view of the array as a list without structural changes.
If you need to add or remove elements, wrap the result in an ArrayList:
String[] array = {"Java", "Python", "C++"};
List list = new ArrayList<>(Arrays.asList(array));
list.add("Go");
System.out.println(list);
This produces:
[Java, Python, C++, Go]
This approach creates a separate, modifiable list that does not affect the original array.
List.of() (Immutable List)Java 9 introduced List.of() for quick immutable list creation:
String[] array = {"Java", "Python", "C++"};
List list = List.of(array);
Notes:
UnsupportedOperationExceptionJava Streams provide a fluent and functional conversion:
String[] array = {"Java", "Python", "C++"};
List list = Arrays.stream(array)
.collect(Collectors.toList());
Better suited when:
Example with transformation:
List upperCaseList = Arrays.stream(array)
.map(String::toUpperCase)
.collect(Collectors.toList());
Methods like Arrays.asList() do not work as expected with primitive arrays (e.g., int[]). Instead, the primitive array is treated as a single object.
int[] array = {1, 2, 3};
List list = Arrays.asList(array);
This produces a list with one element (int[]) — not the values 1, 2, 3.
Use IntStream to box primitive values:
int[] array = {1, 2, 3};
List list = IntStream.of(array)
.boxed()
.collect(Collectors.toList());
Use similar patterns for other primitives like long[] or double[].
For full control or custom logic, convert using a loop:
String[] array = {"Java", "Python", "C++"};
List list = new ArrayList<>();
for (String s : array) {
if (s != null && !s.isBlank()) {
list.add(s);
}
}
This approach enables validation or filtering during conversion.
Popular third-party libraries provide convenience methods:
String[] array = {"Java", "Python", "C++"};
List list = Lists.newArrayList(array);
String[] array = {"Java", "Python", "C++"};
List list = new ArrayList<>(Arrays.asList(array));
These utilities can make code more expressive, especially in large codebases.
| Conversion Method | Mutable List | Backed by Array |
|---|---|---|
Arrays.asList() | No | Yes |
List.of() | No | No |
| Stream + Collect | Yes | No |
| New ArrayList(…) | Yes | No |
| Manual Loop | Yes | No |
Choose based on whether you need to add, remove, or change values.
Arrays.asList() is fast and memory-efficient because it wraps the arrayThese practices produce safer, more maintainable Java code.
Converting an array to a List in Java is straightforward but requires careful choice of method based on mutability and performance needs:
Arrays.asList() — Quick, fixed-size viewnew ArrayList<>(...) — Modifiable collectionList.of() — Immutable listEach approach has its place depending on requirements.
The post Convert Array to List in Java – Methods and Examples appeared first on javatechig.com.
]]>The post Convert String to long in Java – Methods and Examples appeared first on javatechig.com.
]]>String to a primitive long or a Long object in Java is a common task, especially when processing numeric input from the user, reading values from files, or parsing network responses. Java provides standard APIs that perform this conversion reliably with built-in error handling.
In this tutorial you will learn how to convert a Java String to the long type and the Long wrapper class in a safe, efficient way.
Typical scenarios include:
Long.parseLong(String)Long.parseLong() converts a numeric string directly into a primitive long. This is the simplest and most common method.
String numberStr = "1234567890";
long result = Long.parseLong(numberStr);
System.out.println("Converted long: " + result);
NumberFormatException if the string contains non-digit charactersLong.valueOf(String)Long.valueOf() returns a Long object rather than a primitive. It is useful when working with collections or APIs that expect wrapper types.
String numberStr = "9876543210";
Long resultObj = Long.valueOf(numberStr);
long primitive = resultObj.longValue();
System.out.println("Converted Long object: " + resultObj);
Long.parseLong() and wraps the resultWhen parsing user input or external data, always catch exceptions to avoid runtime crashes.
String input = "12ab34";
try {
long value = Long.parseLong(input);
System.out.println("Parsed value: " + value);
} catch (NumberFormatException e) {
System.err.println("Invalid number: " + input);
}
To avoid exceptions and provide a default when parsing fails:
public static long toLongOrDefault(String str, long defaultValue) {
try {
return Long.parseLong(str);
} catch (NumberFormatException e) {
return defaultValue;
}
}
// Usage
long val = toLongOrDefault("abc", 0L);
This pattern is useful in configuration parsing and batch processing.
If you have numeric strings in non-decimal formats (e.g., hex), use:
String hexStr = "1A3F";
long hexValue = Long.parseLong(hexStr, 16);
System.out.println("Hex value: " + hexValue);
This supports bases from 2 to 36.
Always check for null before conversion:
String str = null;
if (str != null) {
long val = Long.parseLong(str);
} else {
// handle null value
}
Passing a null string to parseLong() causes NullPointerException.
| Method | Returns | Throws if invalid | Notes |
|---|---|---|---|
Long.parseLong(String) | long | Yes (NumberFormatException) | Fastest for primitives |
Long.valueOf(String) | Long | Yes (NumberFormatException) | Useful when object type needed |
| Custom fallback | long | No (handled) | Provides default values |
These practices help prevent unhandled exceptions and improve application stability.
The post Convert String to long in Java – Methods and Examples appeared first on javatechig.com.
]]>The post Struts2 Localization and Internationalization – Example and Setup appeared first on javatechig.com.
]]>In this guide, we’ll show how to configure Struts2 for localization and internationalization with message bundles, locale selection, and practical examples.
Struts2 natively supports i18n/l10n using resource bundles (properties files) and configurable locale resolvers.
Struts2 localization works by:
.properties)Ensure your web project includes standard Struts2 dependencies. If you’re using Maven, add:
org.apache.struts
struts2-core
${struts2.version}
Also include a locale interceptor in your stack (default stack includes it).
Create localized message property files under src/main/resources:
GlobalMessages.propertiesGlobalMessages_es.propertiesExample — GlobalMessages.properties:
welcome.message=Welcome to Struts2 Internationalization!
label.username=Username
label.password=Password
Example — GlobalMessages_es.properties:
welcome.message=¡Bienvenido a la Internacionalización de Struts2!
label.username=Nombre de usuario
label.password=Contraseña
These files contain key/value pairs for UI text.
Struts2 automatically uses message bundles when configured properly. Put this in your struts.xml:
This tells Struts2 to load GlobalMessages*.properties as the resource bundle.
Struts2 uses the i18n interceptor by default in the defaultStack. But if you override stacks, ensure it’s present:
This interceptor listens for locale changes (via parameters like request_locale).
On your JSP or HTML page, add language switch links:
English |
Español
When clicked, Struts2 captures request_locale and switches the locale accordingly.
In Struts2 JSPs, use tag to display localized text:
Struts2 will automatically resolve the correct message based on the current locale.
Your Struts2 Action can also use localized text:
public class LoginAction extends ActionSupport {
public String execute() {
String welcome = getText("welcome.message");
addActionMessage(welcome);
return SUCCESS;
}
}
getText() fetches the localized message from the current resource bundle.
Sometimes you need to change the locale via logic (user selection on a form). You can do:
public String changeLanguage() {
Locale locale = new Locale(selectedLang);
ActionContext.getContext().setLocale(locale);
return SUCCESS;
}
Then pass selectedLang from a drop-down (e.g., en, es, hi).
Struts2 integrates with conversion and formatting based on locale. You can format numbers and dates transparently in JSP:
This respects current locale formats.
Always centralize messages in resource bundles — avoid hardcoded strings.
Use key naming conventions (e.g., label.*, msg.*) for clarity.
Support fallback locales by providing default messages.
Keep property files encoded in UTF-8 to avoid encoding issues.
Load only required bundles to keep memory usage optimal.
Missing keys throw exceptions:
Provide default messages or include fallback resource bundles.
Language switch doesn’t persist:
Use Session or cookie to store request_locale parameters.
Encoding issues with special characters:
Ensure .properties files are saved in UTF-8 and Struts2 is configured accordingly.
Struts2 localization and internationalization allow your application to support multiple languages seamlessly. You define message bundles (.properties), configure resource paths in struts.xml, and use Struts2 tags to render localized content. With clean resource organization and proper locale resolution (via request_locale), you can deliver accurate text and formatting to users worldwide.
The post Struts2 Localization and Internationalization – Example and Setup appeared first on javatechig.com.
]]>The post Making BlackBerry Applications Portable Across Multiple Devices appeared first on javatechig.com.
]]>Building portable BlackBerry Java applications that work consistently across multiple devices requires careful handling of UI layout, screen resolution, and font scaling. Unlike modern platforms, BlackBerry devices vary significantly in screen size, resolution, and aspect ratio—especially across legacy JDE 4.5+ devices, which are still widely used in enterprise environments.
This post explains how to handle UI portability in BlackBerry Java applications, with a focus on dynamic font resizing to support multiple screen widths such as Pearl, Curve, Torch, and Storm devices.
BlackBerry devices differ mainly in:
| Device | Screen Width |
|---|---|
| Pearl | Small |
| Curve | Medium |
| Torch | Large |
| Storm | Touch + Wide |
Because of this variation, hardcoded UI dimensions or fixed fonts often break layouts, especially for:
Consider a business application containing:
If text exceeds screen width:
To avoid this, font size must be calculated dynamically based on screen width and content length.
The recommended approach is:
Font.getAdvance()This approach ensures:
Below is a custom paint implementation for dynamically resizing text in a ChoiceField.
paint() Methodprotected void paint(Graphics graphics) {
Resolutions r = new Resolutions();
Font labelFont = r.getFont();
Font font = r.getFont();
int width = r.CustomRowWidth - 3;
int calcWidth = 0;
while (width < (font.getAdvance(label) + maxWidth(font))) {
calcWidth = labelFont.getAdvance(label) + maxWidth(font);
int height = font.getHeight() - 2;
FontFamily fontFamily = Font.getDefault().getFontFamily();
font = fontFamily.getFont(Font.PLAIN, height);
}
graphics.setFont(font);
this.setFont(font);
if (mFontColor != -1) {
graphics.setColor(mFontColor);
}
super.paint(graphics);
}
The maxWidth() method determines the longest string among all available choices in the ChoiceField. This ensures font scaling accounts for worst-case content length.
public int maxWidth(Font font) {
int max = -1;
for (int i = 0; i < this.getSize(); i++) {
String choice = (String) this.getChoice(i);
int width = font.getAdvance(choice);
if (width > max) {
max = width;
}
}
return max;
}
This approach is particularly useful for:
Understanding these UI techniques remains valuable when maintaining or upgrading existing BlackBerry Java applications.
The post Making BlackBerry Applications Portable Across Multiple Devices appeared first on javatechig.com.
]]>The post Java String Length & Trim Example – Guide with Code appeared first on javatechig.com.
]]>In Java, String objects store immutable sequences of characters. Operations like calculating length and trimming whitespace are foundational in parsing, input validation, and data normalization.
Java strings are widely used in:
length())Java’s String.length() method returns the number of characters in a string.
String text = "Hello World";
int size = text.length();
System.out.println("Length: " + size); // Output: Length: 11
"")null; calling on a null reference throws NullPointerExceptiontrim()The trim() method returns a new string with leading and trailing whitespace removed.
String raw = " Java Rocks ";
String trimmed = raw.trim();
System.out.println("Before: '" + raw + "'");
System.out.println("After: '" + trimmed + "'");
Output:
Before: ' Java Rocks '
After: 'Java Rocks'
trim() Removes' '\t\n\risEmpty() with length()A string is empty when its length is zero.
String s = "";
boolean empty = s.isEmpty(); // true
Match with length:
s.length() == 0 // true
isEmpty() is a clearer intent for readability.
null SafelyCalling length() or trim() on null throws an exception. Always check for null:
if (str != null && !str.isEmpty()) {
// safe to call length() or trim()
}
Or use Objects.requireNonNullElse():
String safe = Objects.requireNonNullElse(str, "");
When reading from command line or forms:
String userInput = scanner.nextLine().trim();
This helps remove accidental input spaces.
String path = " /usr/local/bin/ ";
path = path.trim();
Trimmed paths avoid incorrect comparisons.
String message = " Error occurred ";
logger.info(message.trim());
Ensures consistent log formatting.
isEmpty() for Readabilitystring.isEmpty() expresses intent better than string.length() == 0.
NullPointerException is a common pitfall; guard against null references.
strip() (Java 11+)Java 11 adds String.strip() which removes Unicode whitespace:
String s = "\u2002Hello\u2002";
s = s.strip(); // removes Unicode spaces
This is more comprehensive than trim() for international applications.
length() Excludes Spaceslength() counts all characters, including whitespace.
trim() for Internal Spacestrim() only removes leading/trailing spaces, not spaces within the string:
String s = " Hello World ";
s.trim(); // "Hello World", internal space remains
Use replaceAll("\\s+", " ") for internal normalization.
| Method | Purpose |
|---|---|
length() | Returns number of characters |
trim() | Removes leading/trailing whitespace |
isEmpty() | Checks for empty string |
strip() | Unicode whitespace removal (Java 11+) |
The post Java String Length & Trim Example – Guide with Code appeared first on javatechig.com.
]]>The post Struts2 Login Application Tutorial – Complete Setup and Example appeared first on javatechig.com.
]]>You will learn how Struts2 handles requests, binds form parameters to action properties, performs validation, and navigates to views using results.
Struts2 uses the MVC (Model-View-Controller) pattern:
FilterDispatcher (or StrutsPrepareAndExecuteFilter)Struts2 interceptors handle request preparation, parameter binding, validation, and result invocation.
You can bootstrap a Struts2 project using Maven or manually place the required JARs. When using Maven, include:
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.22</version>
</dependency>
</dependencies>
Use the latest stable Struts2 version available in Maven Central.
web.xml)Configure the Struts2 filter to handle requests:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
This filter intercepts all incoming requests and dispatches them through the Struts2 framework.
login.jspPlace this JSP under the web content folder:
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<s:form action="login">
<s:textfield name="username" label="Username" />
<s:password name="password" label="Password" />
<s:submit value="Login" />
</s:form>
<s:if test="hasActionErrors()">
<ul>
<s:actionerror />
</ul>
</s:if>
</body>
</html>
This form submits to the login action with username and password fields.
LoginActionLoginAction.javaCreate an action class with getters and setters for form parameters:
public class LoginAction extends ActionSupport {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String execute() {
if ("admin".equals(username) && "password123".equals(password)) {
return SUCCESS;
} else {
addActionError("Invalid username or password");
return INPUT;
}
}
}
The execute() method checks credentials and returns either SUCCESS or INPUT (to redisplay the login form on failure).
struts.xmlstruts.xmlCreate or update your Struts2 configuration:
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="login" class="com.javatechig.LoginAction">
<result name="success">welcome.jsp</result>
<result name="input">login.jsp</result>
</action>
</package>
</struts>
This defines the login action with two possible results: success and input.
welcome.jspThis page displays after successful login:
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Welcome</title></head>
<body>
<h2>Welcome, <s:property value="username" />!</h2>
<s:form action="logout">
<s:submit value="Logout" />
</s:form>
</body>
</html>
Parameters from LoginAction are automatically available in the view.
Struts2 supports annotation or XML validation.
Create a file named LoginAction-validation.xml next to your action class:
<validators>
<field name="username">
<fieldvalidator type="requiredstring">
<message>Username is required</message>
</fieldvalidator>
</field>
<field name="password">
<fieldvalidator type="requiredstring">
<message>Password is required</message>
</fieldvalidator>
</field>
</validators>
Struts2 will invoke this validator before execute() and return input on validation errors.
After a successful login, you may want to store the user in a session. Modify the action:
Map<String, Object> session = ActionContext.getContext().getSession();
session.put("USER", username);
Then in JSP:
<s:property value="#session.USER" />
Use the session judiciously and clear it on logout.
Struts2 tag library helps to build forms, property displays, and error messages without manual HTML.
Examples:
<s:form> for forms<s:textfield> and <s:password> for inputs<s:submit> for submit button<s:actionerror> to display action errorsThese tags reduce boilerplate and integrate with the Struts2 type converters and interceptors.
From extensive enterprise experience:
These practices lead to maintainable and secure Struts2 applications.
Login does not submit:
Check that the form action matches the action name in struts.xml
Validation not triggered:
Ensure validator config matches action class name (ActionClass-validation.xml)
Session values not available in JSP:
Verify session interceptor is enabled (default stack includes it)
This tutorial showed how to build a login application using Struts2, including:
Struts2 simplifies request handling and form processing using conventions and a flexible interceptor stack. With proper architecture, you can extend this login pattern into a full authentication module.
The post Struts2 Login Application Tutorial – Complete Setup and Example appeared first on javatechig.com.
]]>The post Sort Array Ascending & Descending with Comparator in Java appeared first on javatechig.com.
]]>This updated guide on javatechig.com shows how to sort arrays using Comparator, including object sorting, lambda syntax, and best practices aligned with modern Java standards.
The Comparator interface allows you to:
Unlike natural ordering (Comparable), Comparator gives external sorting rules without modifying the class.
Java’s Arrays.sort() can sort primitives directly:
int[] numbers = {5, 1, 9, 3, 7};
Arrays.sort(numbers); // ascending
For descending on primitives, convert to wrapper type:
Integer[] nums = {5, 1, 9, 3, 7};
Arrays.sort(nums, Collections.reverseOrder());
Assume you have an array of custom objects:
class Person {
String name;
int age;
// Constructor, getters
}
Comparator<Person> byAgeAsc = Comparator.comparingInt(Person::getAge);
Arrays.sort(personArray, byAgeAsc);
This sorts the array by increasing age.
Comparator<Person> byAgeDesc = Comparator.comparingInt(Person::getAge).reversed();
Arrays.sort(personArray, byAgeDesc);
You can chain comparators as needed.
To sort first by age, then name:
Comparator<Person> composite = Comparator
.comparingInt(Person::getAge)
.thenComparing(Person::getName);
Arrays.sort(personArray, composite);
This ensures deterministic ordering with multiple fields.
Arrays.sort(personArray, (p1, p2) -> p1.getName().compareTo(p2.getName()));
Arrays.sort(personArray, (p1, p2) -> p2.getName().compareTo(p1.getName()));
The lambda approach is concise and readable.
When working with lists:
List<Person> list = Arrays.asList(personArray);
list.sort(Comparator.comparing(Person::getAge));
Or for descending:
list.sort(Comparator.comparing(Person::getAge).reversed());
Lists offer more flexibility than arrays for dynamic-sized data.
Java Streams offer a functional approach:
Person[] sorted = Arrays.stream(personArray)
.sorted(Comparator.comparing(Person::getAge))
.toArray(Person[]::new);
Person[] sortedDesc = Arrays.stream(personArray)
.sorted(Comparator.comparing(Person::getAge).reversed())
.toArray(Person[]::new);
Streams allow chaining additional operations like filtering.
== for ComparisonFor object attributes, always use comparison methods (compareTo), not ==.
When sorting, null elements can cause exceptions.
Fix with null‑safe comparator:
Comparator<Person> safeSort = Comparator.nullsLast(
Comparator.comparing(Person::getAge));
This places null elements after non‑null.
Arrays.sort() uses dual‑pivot quicksort for primitives and TimSort for objectsTreeSet| Use Case | Method |
|---|---|
| Ascending primitives | Arrays.sort() |
| Descending primitives | Collections.reverseOrder() |
| Object sort | Comparator.comparing() |
| Multi‑attribute | thenComparing() |
| Streams | stream().sorted() |
The post Sort Array Ascending & Descending with Comparator in Java appeared first on javatechig.com.
]]>