
The OWASP Java Encoder is a Java 1.5+ simple-to-use drop-in high-performance encoder class with no dependencies and little baggage. This project will help Java web developers defend against Cross Site Scripting!
Contextual output encoding for Java 8+. Choose an encoder for the parser context receiving untrusted text: HTML, JavaScript, CSS, XML or a URL component. The core has no runtime dependencies; optional JSP and Jakarta adapters provide view-layer bindings. Encoding is one part of [XSS prevention][xss], alongside safe templates, URL validation and other application controls.
Released 2026-09-28: version 1.5.0 fixes parser-boundary vulnerabilities in JavaScript-in-HTML, CDATA, and XML-comment fragment composition. Versions through 1.4.1 do not contain those fixes. The [signed GitHub release][release] and Maven Central artifacts have been independently verified. See the 1.5.0 release notes, security advisory and VERIFYING.md.
Select the dependency you need.
The three supported artifacts use group ID org.owasp.encoder:
| Artifact ID | Purpose and runtime dependencies |
|---|---|
encoder | Core String/Writer API; no runtime dependencies |
encoder-jsp | Legacy javax JSP tags/EL functions; core plus container-provided JSP API |
encoder-jakarta-jsp | Jakarta JSP tags/EL functions; core plus container-provided Jakarta JSP API |
<dependency>
<groupId>org.owasp.encoder</groupId>
<artifactId>encoder</artifactId>
<version>1.5.0</version>
</dependency>
Replace encoder with one tag adapter artifact ID when needed; each adapter brings
in core. Keep separately managed core/adapter versions aligned. Use one of the
javax or Jakarta taglib JARs: they share org.owasp.encoder.tag and must not coexist
on the same classpath or module path. See the runtime matrix and
dependency/license inventory.
encoder-esapi was retired after 1.4.1 and is not included or supported in
1.5.0. Applications using it must migrate away from the adapter.
Published 1.5.0 API documentation: core, javax JSP and Jakarta JSP.
import org.owasp.encoder.Encode;
out.write("<p>");
Encode.forHtmlContent(out, userText); // Writer overload; no intermediate String
out.write("</p>");
The equivalent String call is Encode.forHtmlContent(userText). Callers supply
trusted surrounding syntax and attribute quotes. Encode raw data once, at the
output boundary; account for any escaping your template engine already performs.
| Destination | API and limits |
|---|---|
| HTML text, including textarea content | forHtmlContent; forHtml also covers quoted ordinary text attributes |
| Quoted HTML text attribute | forHtmlAttribute; not an event-handler expression or URL validator |
| One raw URL component | forUriComponent; assemble with trusted delimiters, validate the URL, then encode for the enclosing HTML attribute |
| JavaScript string | forJavaScript; supply single/double quotes. Ordinary untagged template literal text requires 1.5. Never use in tagged templates, expression bodies, JSON or script URLs |
| JSON string content | forJson (1.5); supply double quotes. Prefer a serializer for a complete document |
Quoted CSS string / CSS url(...) value | forCssString / forCssUrl; validate URLs and obey the method's surrounding-context rules |
| XML 1.0 text / quoted attribute | forXmlContent / forXmlAttribute; forXml covers both |
| XML 1.1 text / quoted attribute | forXml11Content / forXml11Attribute (core 1.4+); requires an XML 1.1 document/parser, not HTML |
| XML CDATA / comment | forCDATA / forXmlComment; not HTML comments |
| Java source string literal | forJava; caller supplies quotes; unpaired surrogates may not compile |
Every listed facade method has String and Writer overloads. The context guide explains nesting, null/Unicode behavior, JavaScript variants, template boundaries, JSON and unsafe contexts. The Java/JSP examples show complete surrounding syntax.
Encoding does not sanitize HTML, validate input/URLs, serialize JSON documents, perform SQL parameterization, or decode/canonicalize data. Use an HTML sanitizer when markup must be allowed; use parameterized queries for SQL. See the [OWASP Java security-library guide][java-libraries] for these distinct roles.
Taglib URIs are identifiers, not URLs that must open in a browser:
| Adapter | Basic identifier | Advanced identifier |
|---|---|---|
| Jakarta | owasp.encoder.jakarta | owasp.encoder.jakarta.advanced |
| javax JSP | https://www.owasp.org/index.php/OWASP_Java_Encoder_Project | Same identifier with #advanced appended |
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@ taglib prefix="e" uri="owasp.encoder.jakarta" %>
<p>${e:forHtmlContent(param.message)}</p>
Use the javax identifier for a javax container. Tags use an empty body and a
required value attribute, for example <e:forHtmlContent value="${param.message}" />.
See bindings and EL evaluation for
basic versus advanced methods and version-sensitive deployment settings. In 1.5,
advanced taglibs expose every Encode.forX(String) context except forJava;
Java source generation is not a JSP context. XML 1.1 bindings are new in 1.5.
Encode.forUri is deprecated in the released API. Version 1.5.0 extends
that deprecation to Encoders.URI, both ForUriTag classes and the forUri
tag/function documentation. All of these entry points are retained through 1.x. Encoding a whole URI does not validate it:
forUri("javascript:alert(1)") returns it unchanged. Existing % signs are encoded
again. Use forUriComponent for one raw parameter name/value, path segment or
fragment; validate complete URLs separately, then use forHtmlAttribute when
placing one in a quoted HTML attribute. Parsing with java.net.URI alone does
not establish safety. See the worked URL example.
Removing the deprecated core/tag API needs a separately reviewed future-major decision; deprecation is not a removal schedule. The separate historical ESAPI adapter is retired rather than carried into 1.5.0.