diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
 
 Package versions follow the [Package Versioning Policy](https://pvp.haskell.org/): in A.B.C, bumps to either A or B represent major versions.
 
+0.20.1
+----
+
+- Support aeson-2.2 [#1695](https://github.com/haskell-servant/servant/pull/1695)
+
 0.20
 ----
 
diff --git a/servant.cabal b/servant.cabal
--- a/servant.cabal
+++ b/servant.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                servant
-version:             0.20
+version:             0.20.1
 
 synopsis:            A family of combinators for defining webservices APIs
 category:            Servant, Web
@@ -93,14 +93,14 @@
   -- We depend (heavily) on the API of these packages:
   -- i.e. re-export, or allow using without direct dependency
   build-depends:
-      http-api-data          >= 0.4.1    && < 0.6
+      http-api-data          >= 0.4.1    && < 0.7
     , singleton-bool         >= 0.1.4    && < 0.2
 
   -- Other dependencies: Lower bound around what is in the latest Stackage LTS.
   -- Here can be exceptions if we really need features from the newer versions.
   build-depends:
       base-compat            >= 0.10.5   && < 0.14
-    , aeson                  >= 1.4.1.0  && < 3
+    , aeson                  >= 1.4.1.0  && < 2.3
     , attoparsec             >= 0.13.2.2 && < 0.15
     , bifunctors             >= 5.5.3    && < 5.7
     , case-insensitive       >= 1.2.0.11 && < 1.3
@@ -167,9 +167,9 @@
 
   -- Additional dependencies
   build-depends:
-      hspec                >= 2.6.0    && < 2.11
+      hspec                >= 2.6.0    && < 2.12
     , QuickCheck           >= 2.12.6.1 && < 2.15
     , quickcheck-instances >= 0.3.19   && < 0.4
 
   build-tool-depends:
-    hspec-discover:hspec-discover >= 2.6.0 && < 2.11
+    hspec-discover:hspec-discover >= 2.6.0 && < 2.12
diff --git a/src/Servant/API/ContentTypes.hs b/src/Servant/API/ContentTypes.hs
--- a/src/Servant/API/ContentTypes.hs
+++ b/src/Servant/API/ContentTypes.hs
@@ -75,13 +75,7 @@
 import           Control.DeepSeq
                  (NFData)
 import           Data.Aeson
-                 (FromJSON (..), ToJSON (..), encode)
-import           Data.Aeson.Parser
-                 (value)
-import           Data.Aeson.Types
-                 (parseEither)
-import           Data.Attoparsec.ByteString.Char8
-                 (endOfInput, parseOnly, skipSpace, (<?>))
+                 (FromJSON (..), ToJSON (..), encode, eitherDecode)
 import           Data.Bifunctor
                  (bimap)
 import qualified Data.ByteString                  as BS
@@ -371,28 +365,15 @@
 --------------------------------------------------------------------------
 -- * MimeUnrender Instances
 
--- | Like 'Data.Aeson.eitherDecode' but allows all JSON values instead of just
--- objects and arrays.
---
--- Will handle trailing whitespace, but not trailing junk. ie.
---
--- >>> eitherDecodeLenient "1 " :: Either String Int
--- Right 1
+-- | Deprecated: since aeson version 0.9 `eitherDecode` has lenient behavior.
 --
--- >>> eitherDecodeLenient "1 junk" :: Either String Int
--- Left "trailing junk after valid JSON: endOfInput"
 eitherDecodeLenient :: FromJSON a => ByteString -> Either String a
-eitherDecodeLenient input =
-    parseOnly parser (cs input) >>= parseEither parseJSON
-  where
-    parser = skipSpace
-          *> Data.Aeson.Parser.value
-          <* skipSpace
-          <* (endOfInput <?> "trailing junk after valid JSON")
+eitherDecodeLenient = eitherDecode
+{-# DEPRECATED eitherDecodeLenient "use eitherDecode instead" #-}
 
 -- | `eitherDecode`
 instance FromJSON a => MimeUnrender JSON a where
-    mimeUnrender _ = eitherDecodeLenient
+    mimeUnrender _ = eitherDecode
 
 -- | @urlDecodeAsForm@
 -- Note that the @mimeUnrender p (mimeRender p x) == Right x@ law only
diff --git a/test/Servant/API/ContentTypesSpec.hs b/test/Servant/API/ContentTypesSpec.hs
--- a/test/Servant/API/ContentTypesSpec.hs
+++ b/test/Servant/API/ContentTypesSpec.hs
@@ -12,7 +12,7 @@
 import           Prelude.Compat
 
 import           Data.Aeson
-                 (FromJSON, ToJSON (..), Value, decode, encode, object, (.=))
+                 (FromJSON, ToJSON (..), Value, decode, encode, object, (.=), eitherDecode)
 import           Data.ByteString.Char8
                  (ByteString, append, pack)
 import qualified Data.ByteString.Lazy                             as BSL
@@ -219,15 +219,13 @@
                 handleCTypeH (Proxy :: Proxy '[JSONorText]) "image/jpeg"
                     "foobar" `shouldBe` (Nothing :: Maybe (Either String Int))
 
-    -- aeson >= 0.9 decodes top-level strings
-    describe "eitherDecodeLenient" $ do
+    describe "eitherDecode is lenient" $ do
 
+        -- Since servant-0.20.1 MimeUnrender JSON instance uses eitherDecode,
+        -- as aeson >= 0.9 supports decoding top-level strings and numbers.
         it "parses top-level strings" $ do
-            let toMaybe = either (const Nothing) Just
-            -- The Left messages differ, so convert to Maybe
-            property $ \x -> toMaybe (eitherDecodeLenient x)
-                `shouldBe` (decode x :: Maybe String)
-
+            property $ \x -> mimeUnrender (Proxy :: Proxy JSON) x
+                `shouldBe` (eitherDecode x :: Either String String)
 
 data SomeData = SomeData { record1 :: String, record2 :: Int }
     deriving (Generic, Eq, Show)
