Apache Tomcat v8.5 not supporting Arabic language

I have a mobile application and its rest Api is written in Jakarta EE by using eclipse and database is an oracle, and of course, we upload war file to the apache server for live application, the apache server version we are using for this is tomcat Apache v8.5. When we insert data through the application while using our local server then Arabic text works fine and properly appears in oracle. but when we upload war file and use the live application through tomcat apache then Arabic text does not work. I use a couple of options but did not get results properly. I also try to set URIEncoding=”UTF-8″ inside the connecter in the server.xml file, but it does not works.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
--><!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 --><Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
 
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

 
  <GlobalNamingResources>
   
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>



  <Service name="Catalina">

  

    <Connector connectionTimeout="20000" port="8080" maxHttpHeaderSize="65536" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
   
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>


    <Engine defaultHost="localhost" name="Catalina">

    
      <Realm className="org.apache.catalina.realm.LockOutRealm">
    
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>

      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>

      <Context docBase="JobVisit" path="/JobVisit" reloadable="true" source="org.eclipse.jst.jee.server:JobVisit"/></Host>
    </Engine>
  </Service>
</Server>

but when i try to convert my string to UTF-8 in eclipse then somehow it works but some alphabets are not coming proper as “ف” appears as “??”.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.google.gson.Gson;
import com.rest.database.DBConnection;

@Path("/arabicTest")

public class MaintenanceRequestRegistrationTest {

    @SuppressWarnings({ "unchecked" })
    @POST
    @Path("arabic")
    @Produces("application/json")
    @Consumes("application/json")

    public String crunchifycreateKCM(InputStream incomingData) throws JSONException {

        Connection dbConnection = null;
        Statement stmt = null;
        //      JSONArray myArray = new JSONArray();
        JSONObject jsarr = new JSONObject();

        try {
            // con.setAutoCommit(false);

            dbConnection = DBConnection.getDBConnection();

            dbConnection.setAutoCommit(false);
            stmt = (Statement) dbConnection.createStatement();
            // System.out.println("Iam entering try catch bloxck");
            new Gson();

            InputStream in = incomingData;

            String a = convertStreamToString(in);

            // System.out.println(a);
            JSONObject json = new JSONObject(a);
            JSONArray kcm = json.getJSONArray("createkcm");

            // System.out.println("length of json data"+kcm.length());
        
                // updating kcmd data
                JSONObject jo = kcm.getJSONObject(0);

                
                String cmremarks = jo.getString("cmremarks");

                cmremarks = new String(cmremarks.getBytes(),"UTF-8");
                
                
                
                    String sqlQuery3 = "insert into test(COL1) values('"+ cmremarks + "')";
                    
                    
                    int count = stmt.executeUpdate(sqlQuery3);
                    
                    if(count>0) {
                        jsarr.put("status", "200");
                    }else {
                        jsarr.put("status", "100");
                    }
                    
                    dbConnection.commit();

                }  catch (Exception e) {
            
            e.printStackTrace();
        } finally {
            // db connection close 16-Nov
            try {
                if (stmt != null)
                    stmt.close();
                if (dbConnection != null)
                    dbConnection.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        // return HTTP response 200 in case of success
        // return Response.status(200).entity(ret.toString()).build();

        System.out.print(jsarr.toString());
        return jsarr.toString();

    
    }
        
    

    private String convertStreamToString(InputStream is) {
        /*
         * To convert the InputStream to String we use the BufferedReader.readLine()
         * method. We iterate until the BufferedReader return null which means there's
         * no more data to read. Each line will appended to a StringBuilder and returned
         * as String.
         */
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}

so please can anyone guide me how to solve this, i also attached my server.xml and java class rest Api code

Answer

I used the two-parameter InputStreamReader constructor as per the suggestion of @PiotrP.Karwasz and it works

private String convertStreamToString(InputStream is) {
        /*
         * To convert the InputStream to String we use the BufferedReader.readLine()
         * method. We iterate until the BufferedReader return null which means there's
         * no more data to read. Each line will appended to a StringBuilder and returned
         * as String.
         */
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }