{"id":19294659,"url":"https://github.com/moesif/moesif-servlet","last_synced_at":"2025-11-11T20:08:05.805Z","repository":{"id":18986470,"uuid":"85748700","full_name":"Moesif/moesif-servlet","owner":"Moesif","description":"Moesif Servlet SDK for API Monitoring, Analytics, and Monetization.","archived":false,"fork":false,"pushed_at":"2025-07-16T18:13:18.000Z","size":629,"stargazers_count":13,"open_issues_count":5,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-07-17T05:31:55.300Z","etag":null,"topics":["analytics","api-analytics","api-logs","api-management","api-monetization","api-monitoring","jakarta","java","java-servlet","logger","logging","monitoring","observability","servlet","servlet-filter","servletfilter","spring-boot","springframework","usage-based-billing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Moesif.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-21T20:13:40.000Z","updated_at":"2025-07-16T18:13:21.000Z","dependencies_parsed_at":"2024-08-27T14:52:29.759Z","dependency_job_id":"3632ed7a-3704-4b83-952a-496f5175879c","html_url":"https://github.com/Moesif/moesif-servlet","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/Moesif/moesif-servlet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moesif%2Fmoesif-servlet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moesif%2Fmoesif-servlet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moesif%2Fmoesif-servlet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moesif%2Fmoesif-servlet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Moesif","download_url":"https://codeload.github.com/Moesif/moesif-servlet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moesif%2Fmoesif-servlet/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265701055,"owners_count":23813747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","api-analytics","api-logs","api-management","api-monetization","api-monitoring","jakarta","java","java-servlet","logger","logging","monitoring","observability","servlet","servlet-filter","servletfilter","spring-boot","springframework","usage-based-billing"],"created_at":"2024-11-09T22:39:08.265Z","updated_at":"2025-11-11T20:08:05.704Z","avatar_url":"https://github.com/Moesif.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Moesif Servlet Integration Documentation\nby [Moesif](https://moesif.com), the [API analytics](https://www.moesif.com/features/api-analytics) and [API monetization](https://www.moesif.com/solutions/metered-api-billing) platform.\n\n[![Built For][ico-built-for]][link-built-for]\n[![Latest Version][ico-version]][link-package]\n[![Software License][ico-license]][link-license]\n[![Source Code][ico-source]][link-source]\n\n`moesif-servlet` is a Java servlet filter that logs incoming API calls and sends to [Moesif](https://www.moesif.com) for API analytics and monitoring.\n\n## Overview\nWe've implemented the SDK as a [Javax servlet filter](https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/Filter.html)\nwithout importing framework specific dependencies. Any framework built on Java [Servlet API](https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/Servlet.html) such as Spring, Struts, and Jersey can use this SDK with minimal configuration.\n\nAn identical implementation `moesif-servlet-jakarta` uses the newer [Jakarta Servlet API](https://tomcat.apache.org/tomcat-10.0-doc/servletapi/jakarta/servlet/Servlet.html). This implementation works with Java 17+ [Tomcat 10](https://tomcat.apache.org/tomcat-10.0-doc/index.html) and [Spring Boot 3.0](https://spring.io/projects/spring-boot). You can find its source code in the [`moesif-servlet-jakarta`](moesif-servlet-jakarta) folder.\n\n## Prerequisites\nBefore using this SDK, make sure you have the following:\n\n- [An active Moesif account](https://moesif.com/wrap)\n- [A Moesif Application ID](#get-your-moesif-application-id)\n\n### Get Your Moesif Application ID\nAfter you log into [Moesif Portal](https://www.moesif.com/wrap), you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:\n\n1. Select the account icon to bring up the settings menu.\n2. Select **Installation** or **API Keys**.\n3. Copy your Moesif Application ID from the **Collector Application ID** field.\n\n\u003cimg class=\"lazyload blur-up\" src=\"images/app_id.png\" width=\"700\" alt=\"Accessing the settings menu in Moesif Portal\"\u003e\n\n## Install the SDK\n\n### Maven Users\n\nAdd the Moesif dependency to your project's `pom.xml` file:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.moesif.servlet\u003c/groupId\u003e\n    \u003cartifactId\u003emoesif-servlet\u003c/artifactId\u003e\n    \u003cversion\u003e1.8.3\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!-- OR for newer Jakarta--\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.moesif.servlet\u003c/groupId\u003e\n    \u003cartifactId\u003emoesif-servlet-jakarta\u003c/artifactId\u003e\n    \u003cversion\u003e2.2.3\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle Users\n\nAdd the Moesif dependency to your project's `build.gradle` file:\n\n```gradle\ndependencies {   \n    compile 'com.moesif.servlet:moesif-servlet:1.8.3'\n}\n\n// OR for newer Jakarta\ndependencies {   \n    compile 'com.moesif.servlet:moesif-servlet-jakarta:2.2.3'\n}\n```\n\n## How to Use\n\nDifferent Java web frameworks have different way of configuring servlet filters.\nThe following sections describe the instructions for different frameworks:\n\n- [Spring Boot](#spring-boot)\n- [Spring MVC](#spring-mvc-java-config)\n- [Jersey Servlet](#jersey-servlet)\n- [Spark Servlet](#spark-servlet)\n- [Generic Java Servlet](#generic-java-servlet)\n- Spring Boot 3.x using Jakarta\n\t- [Spring Boot 3.0 Jakarta with Tomcat](https://github.com/Moesif/moesif-servlet/tree/master/examples-jakarta/spring-boot-starter-example-tomcat)\n\t- [Spring Boot 3.2 Jakarta with Undertow](https://github.com/Moesif/moesif-servlet/tree/master/examples-jakarta/spring-boot-starter-example-undertow)\n\n### Spring Boot\n\nIn your Spring configuration file, install the `MoesifFilter` object.\n\n```java\n\nimport com.moesif.servlet.MoesifFilter;\n\nimport javax.servlet.Filter;\nimport org.springframework.web.servlet.config.annotation.*;\nimport org.springframework.context.annotation.*;\nimport org.springframework.http.converter.*;\n\n@Configuration\npublic class MyConfig implements WebMvcConfigurer {\n\n  @Bean\n  public Filter moesifFilter() {\n    return new MoesifFilter(\"Your Moesif Application Id\");\n  }\n}\n```\n\nTo customize the filter, pass in a object that implements `MoesifConfiguration` such\nas `MoesifConfigurationAdapter`.\n\n```java\n@Configuration\npublic class MyConfig implements WebMvcConfigurer {\n\n  MoesifConfiguration config = new MoesifConfigurationAdapter() {\n    @Override\n    public String getSessionToken(HttpServletRequest request, HttpServletResponse response) {\n      return request.getHeader(\"Authorization\");\n    }\n  };\n\n  @Bean\n  public Filter moesifFilter() {\n    return new MoesifFilter(\"Your Moesif Application Id\", config);\n  }\n}\n```\n\nFor for more information about `MoesifConfiguration`, see the [configuration options](#configuration-options).\n\n\n#### Running the Spring Boot Starter Example\n\nTo run `spring-boot-starter-example`, make sure you have the following installed:\n\n- Java 8+\n- Maven version 3.0.x or above.\n\nYou can check Maven version with the following command:\n\n```sh\nmvn -v\n```\nThen follow these steps:\n\n1. Clone the repository\n\n   ```sh\n   git clone https://github.com/Moesif/moesif-servlet\ncd moesif-servlet\n```\n\n1. In the `spring-boot-starter-example/src/main/java/com/moesif/servlet/spring/MyConfig.java` file, specify [your Moesif Application ID](#get-your-moesif-application-id) in the `applicationId` variable.\n\n2. Compile:\n\n   ```sh\n   cd spring-boot-starter-example\n   mvn clean install\n   ```\n\n3. Run:\n\n   ```sh\n   java -jar target/spring-boot-starter-example*.jar\n   ```\n\n   Alternatively:\n\n   ```sh\n   mvn  spring-boot:run\n   ```\n\n\n5. Using Postman or cURL, make a few API calls to `http://localhost:8080/api` or the port that Spring Boot is running on.\n\n6. Verify that the API calls log to [your Moesif account web portal](https://www.moesif.com/wrap).\n\n### Spring MVC (Java Config)\n\n```java\n\nimport com.moesif.servlet.MoesifFilter;\n\nimport javax.servlet.Filter;\nimport org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;\n\n\npublic class MyWebInitializer extends\n\t\tAbstractAnnotationConfigDispatcherServletInitializer {\n\n\t@Override\n\tprotected Filter[] getServletFilters() {\n\t\treturn new Filter[]{new MoesifFilter(\"Your Moesif Application Id\")};\n\t}\n}\n\n```\n\n### Spring MVC (XML Config)\n\nIn Spring MVC + XML configuration, you can register the filters using `web.xml` file:\n\n```xml\n\n  \u003cfilter\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003cfilter-class\u003ecom.moesif.servlet.MoesifFilter\u003c/filter-class\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003eapplication-id\u003c/param-name\u003e\n      \u003cparam-value\u003eYour Moesif Application Id\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003edebug\u003c/param-name\u003e\n      \u003cparam-value\u003efalse\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003elogBody\u003c/param-name\u003e\n      \u003cparam-value\u003etrue\u003c/param-value\u003e\n    \u003c/init-param\u003e\n  \u003c/filter\u003e\n  \u003cfilter-mapping\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003curl-pattern\u003e/*\u003c/url-pattern\u003e\n  \u003c/filter-mapping\u003e\n```\n\nYou may have to override `onStartup()` to pass in the `MoesifConfiguration` object.\n\n### Jersey Servlet\n\nYou can run Jersey in multiple ways, as a Java servlet or embedded with a Java NIO framework like Grizzly. This subsection focuses on running Jersey as a servlet.\n\nEdit the `web.xml` file and add [your Moesif Application ID](#get-your-moesif-application-id).\n\n```xml\n  \u003cfilter\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003cfilter-class\u003ecom.moesif.servlet.MoesifFilter\u003c/filter-class\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003eapplication-id\u003c/param-name\u003e\n      \u003cparam-value\u003eYour Application Id\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003edebug\u003c/param-name\u003e\n      \u003cparam-value\u003efalse\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003elogBody\u003c/param-name\u003e\n      \u003cparam-value\u003etrue\u003c/param-value\u003e\n    \u003c/init-param\u003e\n  \u003c/filter\u003e\n  \u003cfilter-mapping\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003curl-pattern\u003e/*\u003c/url-pattern\u003e\n  \u003c/filter-mapping\u003e\n\n```\n\n#### Running the Jersey Servlet Example\nTo run `jersey-servlet-example`, make sure you have the following installed:\n\n- Java 8+\n- Maven version 3.0.x or above.\n\nYou can check Maven version with the following command:\n\n```sh\nmvn -v\n```\n\nThen follow these steps:\n\n1. Clone the repository:\n\n   ```sh\n   git clone https://github.com/Moesif/moesif-servlet\ncd moesif-servlet/\n```\n\n2. Edit the `jersey-servlet-example/src/main/webapp/WEB-INF/web.xml` file and add [your Moesif Application ID](#get-your-moesif-application-id).\n\n\n3. Compile and run:\n\n   ```sh\n   cd jersey-servlet-example\n   mvn clean install\n   java -jar target/dependency/webapp-runner.jar target/*.war\n   ```\n\n4. Go to `http://localhost:8080/api/demo` or the port that Tomcat is running on.\n\nIn your [Moesif account web portal](https://moesif.com/wrap), you should see events logged and monitored.\n\nYou can shut down the server manually by pressing \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eC\u003c/kbd\u003e.\n\n### Spark Servlet\n\nYou can run Spark in multiple ways, as a Java servlet or embedded with a server like Jetty. This subsection focuses on running Spark as a servlet.\n\nEdit the `web.xml` file and add [your Moesif Application ID](#get-your-moesif-application-id).\n\n```xml\n  \u003cfilter\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003cfilter-class\u003ecom.moesif.servlet.MoesifFilter\u003c/filter-class\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003eapplication-id\u003c/param-name\u003e\n      \u003cparam-value\u003eYour Moesif Application Id\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003edebug\u003c/param-name\u003e\n      \u003cparam-value\u003efalse\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003elogBody\u003c/param-name\u003e\n      \u003cparam-value\u003etrue\u003c/param-value\u003e\n    \u003c/init-param\u003e\n  \u003c/filter\u003e\n  \u003cfilter-mapping\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003curl-pattern\u003e/*\u003c/url-pattern\u003e\n  \u003c/filter-mapping\u003e\n\n```\n\n#### Running the Spark Servlet Example\nTo run `spark-servlet-example`, make sure you have the following installed:\n\n- Java 8+\n- Maven version 3.0.x or above.\n\nYou can check Maven version with the following command:\n\n```sh\nmvn -v\n```\n\nThen follow these steps:\n\n1. Clone the repository:\n\n   ```sh\n   git clone https://github.com/Moesif/moesif-servlet\n   cd moesif-servlet\n   ```\n\n2. Edit the `spark-servlet-example/src/main/webapp/WEB-INF/web.xml` file and add [your Moesif Application ID](#get-your-moesif-application-id) there. In the [`spark-servlet-example/src/main/java/com/moesif/servlet/spark/example/SparkDemo.java` file](https://github.com/Moesif/moesif-servlet/blob/ab1565d66ec6eff2076ca1e193506d0dc8de7163/spark-servlet-example/src/main/java/com/moesif/servlet/spark/example/SparkDemo.java#L24), add your Moesif Application ID as an argument to `MoesifAPIClient` object.\n\n3. Compile and run:\n\n   ```sh\n   cd spark-servlet-example\n   mvn clean install\n   java -jar target/dependency/webapp-runner.jar target/*.war\n   ```\n\n4. Go to `http://localhost:8080/api/demo` or the port that Tomcat is running on.\n\nIn your [Moesif account web portal](https://moesif.com/wrap), you should see event logged and monitored.\n\nYou can shut down the server manually by pressing \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eC\u003c/kbd\u003e.\n\n### Generic Java Servlet\nEdit the `web.xml` file and add [your Moesif Application ID](#get-your-moesif-application-id).\n\n```xml\n  \u003cfilter\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003cfilter-class\u003ecom.moesif.servlet.MoesifFilter\u003c/filter-class\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003eapplication-id\u003c/param-name\u003e\n      \u003cparam-value\u003eYour Moesif Application Id\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003edebug\u003c/param-name\u003e\n      \u003cparam-value\u003efalse\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003elogBody\u003c/param-name\u003e\n      \u003cparam-value\u003etrue\u003c/param-value\u003e\n    \u003c/init-param\u003e\n  \u003c/filter\u003e\n  \u003cfilter-mapping\u003e\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003curl-pattern\u003e/*\u003c/url-pattern\u003e\n  \u003c/filter-mapping\u003e\n\n```\n\n#### Running the Generic Servlet Example\n\n`servlet-example` implements the Servlet Filter directly in a generic servlet app rather than using a higher level framework like Spring MVC or Spring Boot.\n\nTo run this example, make sure you have the following installed:\n\n- Java 8+\n- Maven version 3.0.x or above.\n\nYou can check Maven version with the following command:\n\n```sh\nmvn -v\n```\n\nThen follow these steps:\n\n1. Clone the repository:\n\n   ```sh\n   git clone https://github.com/Moesif/moesif-servlet\ncd moesif-servlet\n```\n\n1. Edit the `servlet-example/src/main/webapp/WEB-INF/web.xml` file and add [your Moesif Application ID](#get-your-moesif-application-id) there.\n\n2. Compile and run:\n\n   ```sh\n   cd servlet-example\n   mvn clean install\n   java -jar target/dependency/webapp-runner.jar target/*.war\n   ```\n\n3. Go to `http://localhost:8080/api/demo` or the port that Tomcat is running on.\n\nIn your [Moesif account web portal](https://moesif.com/wrap), you should see event logged and monitored.\n\nYou can shut down the server manually by pressing \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eC\u003c/kbd\u003e.\n\n## Troubleshoot\nFor a general troubleshooting guide that can help you solve common problems, see [Server Troubleshooting Guide](https://www.moesif.com/docs/troubleshooting/server-troubleshooting-guide/). To print debug logs to help troubleshooting, follow the instructions in [How to Print Debug Logs](#how-to-print-debug-logs).\n\nOther troubleshooting supports:\n\n- [FAQ](https://www.moesif.com/docs/faq/)\n- [Moesif support email](mailto:support@moesif.com)\n\n### How to Print Debug Logs\n\nIf you need to print debugs logs, you can set the debug switch when initializing the MoesifFilter object.\n\n```java\nMoesifFilter filter = new MoesifFilter(\"Your Moesif Application Id\", debug)\n```\n\nIf you are using XML configuration, you can set the debug switch like below:\n\n```xml\n    \u003cfilter-name\u003eMoesifFilter\u003c/filter-name\u003e\n    \u003cfilter-class\u003ecom.moesif.servlet.MoesifFilter\u003c/filter-class\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003eapplication-id\u003c/param-name\u003e\n      \u003cparam-value\u003eYour Moesif Application Id\u003c/param-value\u003e\n    \u003c/init-param\u003e\n    \u003cinit-param\u003e\n      \u003cparam-name\u003edebug\u003c/param-name\u003e\n      \u003cparam-value\u003etrue\u003c/param-value\u003e\n    \u003c/init-param\u003e\n  \u003c/filter\u003e\n```\n\n## How to Test\n\n1. Manually clone this repository.\n2. Enter `moesif-servlet` and run `mvn clean install -U -Dgpg.skip` if you haven't done so.\n3. Add your own application id to `src/test/java/com/moesif/servlet/MoesifServletTests.java`. You can find your Moesif Application Id from [_Moesif Dashboard_](https://www.moesif.com/) -\u003e _Top Right Menu_ -\u003e _Installation_\n4. From terminal/cmd navigate to the root directory of the moesif-servlet.\n5. Invoke `mvn -Dtest=MoesifServletTests test` to run the tests.\n\n\n## Configuration Options\n\nTo configure the filter, extend the `MoesifConfigurationAdapter` class to override a few configuration parameters\nor implement the entire `MoesifConfiguration` interface. Both will achieve similar results.\n\n### Parameters\nOverride the following parameters, if needed.\n\n#### `batchSize`\n\n| Required | Type | Default Value | Description |\n| -- | -- | -- | -- |\n| No | Number | 100 | The batch size of API events that triggers flushing of queue and sending the data to Moesif. |\n\n#### `batchMaxTime`\n\n| Required | Type | Default Value | Description |\n| -- | -- | -- | -- |\n| No | Number (seconds) | 2 | The maximum wait time (approximately) before the SDK triggers flushing of the queue and sends data to Moesif. |\n\n#### `queueSize`\n| Required | Type | Default Value | Description |\n| -- | -- | -- | -- |\n| No | Number | 1000000 | Maximum queue capacity to hold events in memory. |\n\n#### `retry`\n| Required | Type | Default Value | Description |\n| -- | -- | -- | -- |\n| No | Number | 0 | Number of time to retry if the SDK fails to send data to Moesif. Set the value between 0 to 3. |\n\n#### `updateConfigTime`\n| Required | Type | Default Value | Description |\n| -- | -- | -- | -- |\n| No | Number (seconds) | 300 (seconds) | The maximum wait time (approximately) to pull the latest app configuration and update the cache. |\n\n#### `logBody`\n| Required | Type | Default Value | Description |\n| -- | -- | -- | -- |\n| No | boolean | true | Whether to log request and response body to Moesif. |\n\n#### `requestMaxBodySize`\n| Required | Type | Default Value | Description                                                                                  |\n| -- | -- |---------------|----------------------------------------------------------------------------------------------|\n| No | Number | 1,048,576     | The maximum request body size in bytes to log when sending the data to Moesif. Default 1 MiB |\n\n#### `responseMaxBodySize`\n| Required | Type | Default Value | Description                                                                     |\n| -- | -- |---------------|---------------------------------------------------------------------------------|\n| No | Number | 1,048,576     | The maximum response body size in bytes to log when sending the data to Moesif. Default 1 MiB |\n\n\n### Interface Methods\n\nThe `MoesifConfiguration` class provides several methods that you can override to customize its behavior or extract information from your requests/responses with custom logic.\n\n#### Overridable Methods\n\n1. `boolean skip (HttpServletRequest request, HttpServletResponse response)`\n2. `String getApiVersion (HttpServletRequest request, HttpServletResponse response)`\n3. `Object getMetadata (HttpServletRequest request, HttpServletResponse response)`\n4. `String identifyUser (HttpServletRequest request, HttpServletResponse response)`\n5. `String identifyCompany (HttpServletRequest request, HttpServletResponse response)`\n6. `String getSessionToken (HttpServletRequest request, HttpServletResponse response)`\n7. `EventModel maskContent (EventModel eventModel)`\n\n#### Calling Behavior\n\nThe above methods are called at different times during the processing of each HTTP request and response.\n\n*On Request Only*\n\n- `skip`, this is called first before the Moesif filter processes the request any further.  If true, the MoesifFilter immediately continues the request through the filter chain without logging or any further processing by Moesif.\n- `getApiVersion`, called on request only\n\n*On Request and On Response*\n\nEach of the following interface methods is called **twice** per HTTP request/response cycle to expose information from the request, the response, or both, depending on your needs.\n- `getMetadata`\n- `identifyUser`\n- `identifyCompany`\n- `getSessionToken`\n\n1. **On Request:** The method is called before the request is fully processed and there is no response yet, so the response `HttpServletResponse` parameter is always `null` for the first call. \n2. **On Response:** The method is called a second time after the response is generated by your application. Both `HttpServletRequest` and `HttpServletResponse` are passed as parameters and non-null.\n\n**Note:** If you need to use these callbacks for governance features, such as transforming or blocking requests, the necessary information must be available in the **request** phase. This is because request governance operates before the response is generated.\n\n*After Request/Response Processing*\n\n- `maskContent`, is called twice but at each point, after all of the above methods are called, and this method gets the partial then the final Moesif Event model that would eventually be sent. This method allows you to remove sensitive data from the HTTP headers or body or inspect/change any Event property in general before sending to Moesif\n\n\n### `public boolean skip(HttpServletRequest request, HttpServletResponse response)`\nReturn `true` if you want to skip logging a\nrequest to Moesif. For example, you may skip requests like health probes.\n\n```java\n  @Override\n  public boolean skip(HttpServletRequest request, HttpServletResponse response) {\n    // Skip logging health probes\n    return request.getRequestURI().contains(\"health/probe\");\n  }\n```\n\n### 2. `public Object getMetadata(HttpServletRequest request, HttpServletResponse response)`\nReturn a Java Object that allows you to add custom metadata to the event like instanceId or traceId.\nThe metadata must be a simple Java object that can be converted to JSON.\n\n```java\npublic Object getMetadata(HttpRequest request, ClientHttpResponse response) {\n  Map\u003cString, Object\u003e customMetadata = new HashMap\u003cString, Object\u003e();\n  customMetadata.put(\"service_name\", System.getProperty(\"app_name\"));\n  return customMetadata;\n}\n```\n\n### 3. `public String identifyUser(HttpServletRequest request, HttpServletResponse response)`\nHighly recommended.\n\nReturns a user ID as a String. This enables Moesif to attribute API requests to individual users so you can understand who is calling your API.\n\nYou can use this function simultaneously with [`identifyCompany()`](#4-public-string-identifycompanyhttpservletrequest-request-httpservletresponse-response) to track both individual customers and the companies that they are a part of.\n\n```java\n  @Override\n  public String identifyUser(HttpServletRequest request, HttpServletResponse response) {\n    if (request.getUserPrincipal() == null) {\n        return null;\n    }\n    return request.getUserPrincipal().getName();\n  }\n```\n\n### 4. `public String identifyCompany(HttpServletRequest request, HttpServletResponse response)`\nReturns a company ID as a String.\n\nIf you have a B2B business, this enables Moesif to attribute API requests to specific companies or organizations so you can understand which accounts are calling your API. You can use this function simultaneously with [`identifyUser()`](#3-public-string-identifyuserhttpservletrequest-request-httpservletresponse-response) to track both individual customers and the companies they are a part of.\n\n```java\n  @Override\n  public String identifyCompany(HttpServletRequest request, HttpServletResponse response) {\n    return \"12345\";\n  }\n```\n\n### 5. `public String getSessionToken(HttpServletRequest request, HttpServletResponse response)`\n\nMoesif automatically detects the end user's session token or API key, but you can manually define the token for finer control.\n\n```java\n  @Override\n  public String getSessionToken(HttpServletRequest request, HttpServletResponse response) {\n    return request.getHeader(\"Authorization\");\n  }\n```\n\nThe following example uses the session ID:\n\n```java\n  @Override\n  public String getSessionToken(HttpServletRequest request, HttpServletResponse response) {\n    return request.getRequestedSessionId();\n  }\n```\n\n### 6. `public String getApiVersion(HttpServletRequest request, HttpServletResponse response)`\nReturns a string to tag requests with a specific version of your API.\n\n```java\n  @Override\n  public String getApiVersion(HttpServletRequest request, HttpServletResponse response) {\n    return request.getHeader(\"X-Api-Version\");\n  }\n```\n\n### 7. `public EventModel maskContent(EventModel eventModel)`\nIf you want to remove any sensitive data in the HTTP headers or body before sending to Moesif, use `maskContent`.\n\n#### Usage Examples\n\nFor the methods which are called once on request and again on response, here are the patterns we recommend for each use case of reading a value from the request only, reading a value from the response only, and logging values that require both request and response.\n\n##### 1. Reading a Value from the Request Only\n\nIf you need to extract information that is available in the request, you can implement the method using only the `request` parameter.\n\n```java\n@Override\npublic String identifyUser(HttpServletRequest request, HttpServletResponse response) {\n    // Extract user ID from request header\n    return request.getHeader(\"X-User-Id\");\n}\n```\n\nIn this example, the user ID is obtained from a custom request header. Since this information is available in the request, it can be accessed during both the request and response phases.\n\n##### 2. Reading a Value from the Response Only\n\nIf the information you need is only available in the response, you can implement the method to check if the `response` is not null.\n\n```java\n@Override\npublic String identifyCompany(HttpServletRequest request, HttpServletResponse response) {\n    if (response != null) {\n        // Extract company ID from response header\n        return response.getHeader(\"X-Company-Id\");\n    }\n    // Response not yet available, return null to set no value on request phase\n    return null;\n}\n```\n\nIn this example, the company ID is obtained from a response header. Since the response is `null` during the request phase, we return `null` in that case.\n\n##### 3. Reading a Value Using Both Request and Response\n\nIf you need to use information from both the request and the response, you can implement the method accordingly.\n\n```java\n@Override\npublic Object getMetadata(HttpServletRequest request, HttpServletResponse response) {\n    Map\u003cString, Object\u003e metadata = new HashMap\u003c\u003e();\n    // Add request information to metadata up front in the event of an error response\n    metadata.put(\"value_id\", request.getHeader(\"X-Value-Id\"));\n\n    if (response != null) {\n        // if you only need a request value when response is also available\n        int start = request.getIntHeader(\"X-Start-Value\");\n\n        int end = response.getIntHeader(\"X-End-Value\");\n        metadata.put(\"value_delta\", end - start);\n    }\n    // The on request value is set first, then overwritten by the on response return value\n    // if a value is set on request, but null is returned on response, the on request value is retained and logged\n    return metadata;\n}\n```\n\nIn this example, we build a metadata object that includes information from both the request and the response. During the request phase, `response` is `null`, so only request information is read. During the response phase, both request and response information are read for the complete .\n\n\n## Building `moesif-servlet` Locally\nIf you are contributing to `moesif-servlet`, you can build it locally and install in local Maven Repo:\n\n```sh\ncd moesif-servlet\nmvn clean install\n```\n## Examples\nThe following examples demonstrate how to add and update customer information.\n\nThe methods these examples use are accessible through the Moesif Java API library that this SDK already imports as a dependency.\n\n### Update a Single User\nTo create or update a [user](https://www.moesif.com/docs/getting-started/users/) profile in Moesif, use the `updateUser()` function.\n\n```java\nMoesifFilter filter = new MoesifFilter(\"Your Moesif Application Id\", new MoesifConfiguration());\n\n// Campaign object is optional, but useful if you want to track ROI of acquisition channels\n// See https://www.moesif.com/docs/api#users for campaign schema\nCampaignModel campaign = new CampaignBuilder()\n        .utmSource(\"google\")\n        .utmCampaign(\"cpc\")\n        .utmMedium(\"adwords\")\n        .utmTerm(\"api+tooling\")\n        .utmContent(\"landing\")\n        .build();\n\n// Only userId is required\n// metadata can be any custom object\nUserModel user = new UserBuilder()\n    .userId(\"12345\")\n    .companyId(\"67890\") // If set, associate user with a company object\n    .campaign(campaign)\n    .metadata(APIHelper.deserialize(\"{\" +\n        \"\\\"email\\\": \\\"johndoe@acmeinc.com\\\",\" +\n        \"\\\"first_name\\\": \\\"John\\\",\" +\n        \"\\\"last_name\\\": \\\"Doe\\\",\" +\n        \"\\\"title\\\": \\\"Software Engineer\\\",\" +\n        \"\\\"sales_info\\\": {\" +\n            \"\\\"stage\\\": \\\"Customer\\\",\" +\n            \"\\\"lifetime_value\\\": 24000,\" +\n            \"\\\"account_owner\\\": \\\"mary@contoso.com\\\"\" +\n          \"}\" +\n        \"}\"))\n    .build();\n\nfilter.updateUser(user);\n```\n\nThe `metadata` field can contain any customer demographic or other info you want to store. Moesif only requires the `userId` field.\n\nThis method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in [Moesif Java API reference](https://www.moesif.com/docs/api?java#update-a-user).\n\n\n### Update Users in Batch\nTo update a list of [users](https://www.moesif.com/docs/getting-started/users/) in one batch, use the `updateUsersBatch()` function. You can update users synchronously or asynchronously on a background thread. Unless you require synchronous behavior, we recommend the async versions.\n\n```java\nMoesifFilter filter = new MoesifFilter(\"Your Moesif Application Id\", new MoesifConfiguration());\n\nList\u003cUserModel\u003e users = new ArrayList\u003cUserModel\u003e();\n\nUserModel userA = new UserBuilder()\n        .userId(\"12345\")\n        .companyId(\"67890\")\n        .campaign(campaign)\n        .metadata(APIHelper.deserialize(\"{\" +\n            \"\\\"email\\\": \\\"johndoe@acmeinc.com\\\",\" +\n            \"\\\"first_name\\\": \\\"John\\\",\" +\n            \"\\\"last_name\\\": \\\"Doe\\\",\" +\n            \"\\\"title\\\": \\\"Software Engineer\\\",\" +\n            \"\\\"sales_info\\\": {\" +\n                \"\\\"stage\\\": \\\"Customer\\\",\" +\n                \"\\\"lifetime_value\\\": 24000,\" +\n                \"\\\"account_owner\\\": \\\"mary@contoso.com\\\"\" +\n              \"}\" +\n            \"}\"))\n        .build();\nusers.add(userA);\n\nUserModel userB = new UserBuilder()\n        .userId(\"54321\")\n        .companyId(\"67890\")\n        .campaign(campaign)\n        .metadata(APIHelper.deserialize(\"{\" +\n            \"\\\"email\\\": \\\"johndoe@acmeinc.com\\\",\" +\n            \"\\\"first_name\\\": \\\"John\\\",\" +\n            \"\\\"last_name\\\": \\\"Doe\\\",\" +\n            \"\\\"title\\\": \\\"Software Engineer\\\",\" +\n            \"\\\"sales_info\\\": {\" +\n                \"\\\"stage\\\": \\\"Customer\\\",\" +\n                \"\\\"lifetime_value\\\": 24000,\" +\n                \"\\\"account_owner\\\": \\\"mary@contoso.com\\\"\" +\n              \"}\" +\n            \"}\"))\n        .build();\nusers.add(userB);\n\nfilter.updateUsersBatch(users, callBack);\n```\n\nThe `metadata` field can contain any customer demographic or other info you want to store. MOesif only requires the `userId` field.\n\nThis method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in\n[Moesif Java API reference](https://www.moesif.com/docs/api?java#update-users-in-batch).\n\n### Update a Single Company\nTo update a single [company](https://www.moesif.com/docs/getting-started/companies/), use the `updateCompany()` function.\n\n```java\nMoesifFilter filter = new MoesifFilter(\"Your Moesif Application Id\", new MoesifConfiguration());\n\n// Campaign object is optional, but useful if you want to track ROI of acquisition channels\n// See https://www.moesif.com/docs/api#update-a-company for campaign schema\nCampaignModel campaign = new CampaignBuilder()\n        .utmSource(\"google\")\n        .utmCampaign(\"cpc\")\n        .utmMedium(\"adwords\")\n        .utmTerm(\"api+tooling\")\n        .utmContent(\"landing\")\n        .build();\n\n// Only companyId is required\n// metadata can be any custom object\nCompanyModel company = new CompanyBuilder()\n    .companyId(\"67890\")\n    .companyDomain(\"acmeinc.com\") // If set, Moesif will enrich your profiles with publicly available info \n    .campaign(campaign) \n    .metadata(APIHelper.deserialize(\"{\" +\n        \"\\\"org_name\\\": \\\"Acme, Inc\\\",\" +\n        \"\\\"plan_name\\\": \\\"Free\\\",\" +\n        \"\\\"deal_stage\\\": \\\"Lead\\\",\" +\n        \"\\\"mrr\\\": 24000,\" +\n        \"\\\"demographics\\\": {\" +\n            \"\\\"alexa_ranking\\\": 500000,\" +\n            \"\\\"employee_count\\\": 47\" +\n          \"}\" +\n        \"}\"))\n    .build();\n\nfilter.updateCompany(company);\n```\n\nThe `metadata` field can contain any company demographic or other information you want to store. Moesif only requires the `companyId` field.\n\nThis method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in [Moesif Java API reference](https://www.moesif.com/docs/api?java#update-a-company).\n\n### Update Companies in Batch\nTo update a list of [companies](https://www.moesif.com/docs/getting-started/companies/) in one batch, use the `updateCompaniesBatch()` function. You can update companies synchronously or asynchronously on a background thread. Unless you require synchronous behavior, we recommend the async versions.\n\n```java\nMoesifFilter filter = new MoesifFilter(\"Your Moesif Application Id\", new MoesifConfiguration());\n\n// Campaign object is optional, but useful if you want to track ROI of acquisition channels\n// See https://www.moesif.com/docs/api#update-a-company for campaign schema\nCampaignModel campaign = new CampaignBuilder()\n        .utmSource(\"google\")\n        .utmCampaign(\"cpc\")\n        .utmMedium(\"adwords\")\n        .utmTerm(\"api+tooling\")\n        .utmContent(\"landing\")\n        .build();\n\n// Only companyId is required\n// metadata can be any custom object\nCompanyModel company = new CompanyBuilder()\n    .companyId(\"67890\")\n    .companyDomain(\"acmeinc.com\") // If set, Moesif will enrich your profiles with publicly available info \n    .campaign(campaign) \n    .metadata(APIHelper.deserialize(\"{\" +\n        \"\\\"org_name\\\": \\\"Acme, Inc\\\",\" +\n        \"\\\"plan_name\\\": \\\"Free\\\",\" +\n        \"\\\"deal_stage\\\": \\\"Lead\\\",\" +\n        \"\\\"mrr\\\": 24000,\" +\n        \"\\\"demographics\\\": {\" +\n            \"\\\"alexa_ranking\\\": 500000,\" +\n            \"\\\"employee_count\\\": 47\" +\n          \"}\" +\n        \"}\"))\n    .build();\n\nfilter.updateCompaniesBatch(companies);\n```\n\nThe `metadata` field can contain any company demographic or other information you want to store. Moesif only requires the `companyId` field.\n\nThis method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in [Moesif Java API reference](https://www.moesif.com/docs/api?java#update-companies-in-batch).\n\n### Update a Single Subscription\n\nTo create or update a subscription profile in Moesif, use the `updateSubscription()` function.\n\n```java\nMoesifFilter filter = new MoesifFilter(\"Your Moesif Application Id\", new MoesifConfiguration());\n\n// Only subscriptionId, companyId, and status are required\n// metadata can be any custom object\nSubscriptionModel subscription = new SubscriptionBuilder()\n    .subscriptionId(\"sub_12345\")\n    .companyId(\"67890\")\n    .status(\"active\")\n    .metadata(APIHelper.deserialize(\"{\" +\n        \"\\\"email\\\": \\\"johndoe@acmeinc.com\\\",\" +\n        \"\\\"string_field\\\": \\\"value_1\\\",\" +\n        \"\\\"number_field\\\": 0,\" +\n        \"\\\"object_field\\\": {\" +\n        \"\\\"field_1\\\": \\\"value_1\\\",\" +\n        \"\\\"field_2\\\": \\\"value_2\\\"\" +\n        \"}\" +\n        \"}\"))\n    .build();\n\nfilter.updateSubscription(subscription);\n```\n\nThe metadata field can store any subscription-related information you wish to keep. The `subscription_id`, `company_id`, and `status` fields are all required. This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in [Moesif Java API reference](https://www.moesif.com/docs/api?java#update-a-subscription).\n\n## Update Subscriptions in Batch\n\nTo update a list of subscriptions in one batch, use the `updateSubscriptionsBatch()` function.\n\nYou can update subscriptions synchronously or asynchronously on a background thread. Unless you require synchronous behavior, we recommend the async versions.\n\n```java\nMoesifFilter filter = new MoesifFilter(\"Your Moesif Application Id\", new MoesifConfiguration());\n\nList\u003cSubscriptionModel\u003e subscriptions = new ArrayList\u003c\u003e();\nsubscriptions.add(new SubscriptionBuilder()\n    .subscriptionId(\"sub_12345\")\n    .companyId(\"67890\")\n    .status(\"active\")\n    .metadata(APIHelper.deserialize(\"{\" +\n        \"\\\"email\\\": \\\"johndoe@acmeinc.com\\\",\" +\n        \"\\\"string_field\\\": \\\"value_1\\\",\" +\n        \"\\\"number_field\\\": 0,\" +\n        \"\\\"object_field\\\": {\" +\n        \"\\\"field_1\\\": \\\"value_1\\\",\" +\n        \"\\\"field_2\\\": \\\"value_2\\\"\" +\n        \"}\" +\n        \"}\"))\n    .build());\n\n// Add more subscriptions as needed\n\nfilter.updateSubscriptionsBatch(subscriptions);\n```\n\nThe `subscription_id`, `company_id`, and `status` fields are required for each subscription in the list. This method is a convenient helper that calls the Moesif API library. For more information, see the function documentation in [Moesif Java API reference](https://www.moesif.com/docs/api?java#update-subscriptions-in-batch).\n\n## How to Get Help\nIf you face any issues using Moesif Servlet SDK, try the [troubheshooting guidelines](#troubleshoot). For further assistance, reach out to our [support team](mailto:support@moesif.com).\n\n## Explore Other Integrations\n\nExplore other integration options from Moesif:\n\n- [Server integration options documentation](https://www.moesif.com/docs/server-integration//)\n- [Client integration options documentation](https://www.moesif.com/docs/client-integration/)\n\n[ico-built-for]: https://img.shields.io/badge/built%20for-servlet-blue.svg\n[ico-version]: https://img.shields.io/maven-central/v/com.moesif.servlet/moesif-servlet\n[ico-license]: https://img.shields.io/badge/License-Apache%202.0-green.svg\n[ico-source]: https://img.shields.io/github/last-commit/moesif/moesif-servlet.svg?style=social\n\n[link-built-for]: https://en.wikipedia.org/wiki/Java_servlet\n[link-package]: https://search.maven.org/artifact/com.moesif.servlet/moesif-servlet\n[link-license]: https://raw.githubusercontent.com/Moesif/moesif-servlet/master/LICENSE\n[link-source]: https://github.com/moesif/moesif-servlet\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoesif%2Fmoesif-servlet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoesif%2Fmoesif-servlet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoesif%2Fmoesif-servlet/lists"}