Tutorials:MySQL and Red5

From Red5Tutorials

(Redirected from Howtos:Tomcat)
Jump to: navigation, search

Contents

Implementing mySQL support

Prerequisites

and place it in {TOMCAT_HOME}\common\lib\

  • A running mySQL server with a database you can access

Method 1a: mySQL 'inline'

hard to use, insecure, but great for testing

    private void logMessage(String msg) {
        Statement stmt = null;

        try {
	        Connection	conn = DriverManager.getConnection("jdbc:mysql://host.xxxx.com/dbname","username","password");
	
			// Do something with the Connection
			stmt = conn.createStatement();
			stmt.execute(
			    "INSERT INTO log_lobby_chat (message) "
			    + "VALUES ('" + msg.replace("'","") + "')");
			stmt.close();
			stmt = null;
			
			conn.close();
			conn = null;
		
		} catch (SQLException ex) {
			log.debug("SQLException: " + ex.getMessage());
			log.debug("SQLState: " + ex.getSQLState());
			log.debug("VendorError: " + ex.getErrorCode());
		}               
	} // end logMessage

Method 1b: mySQL credentials from a properties file

This method loads a configuration file (database.properties) holding all information to let Tomcat connect to the MySQL database.

Step 1: setting up database.properties

Put the following lines in a file called database.properties and store it in the directory WEB-INF of {RED5_HOME}.

jdbc.drivers = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://yourmysqlhost.domain.com/yourdatabasenamehere
jdbc.username = your_username_here
jdbc.password = your_password_here

Step 2: the (Red5) java code

import java.io.*;

private static Connection getConnection() throws SQLException, IOException
{
   Properties props = new Properties();
   // Looks for the file 'database.properties' in {TOMCAT_HOME}\webapps\{RED5_HOME}\WEB-INF\
   FileInputStream in = new FileInputStream(System.getProperty("red5.config_root") + "/database.properties");
   props.load(in);
   in.close();
   
   // It will load the driver String from properties
   String drivers = props.getProperty("jdbc.drivers");
   if(drivers != null) {
	System.setProperty("jdbc.drivers", drivers); // If drivers are not set in properties, set them now.
	// Class.forName("com.mysql.jdbc.Driver").newInstance();
   }
   
   String url = props.getProperty("jdbc.url");
   String username = props.getProperty("jdbc.username");
   String password = props.getProperty("jdbc.password");

   return DriverManager.getConnection(url, username, password);
}


public void logMessage(String msg) {
  Statement stmt = null;

  try {
    Connection conn = getConnection(); // Get connection from properties file

    // Do something with the Connection
    stmt = conn.createStatement();
    stmt.execute(
      "INSERT INTO log_chatroom (message) "
      + "VALUES ('" + msg.replace("'","''") + "')");
    stmt.close();
    stmt = null;

    conn.close();
    conn = null;

  } catch (IOException ex) {
      log.error("SQLException: " + ex.getMessage());
  } catch (SQLException ex) {
      log.error("SQLException: " + ex.getMessage());
      log.error("SQLState: " + ex.getSQLState());
      log.error("VendorError: " + ex.getErrorCode());
  }               
}

Method 2: JNDI (connection pool)

Tomcat ships with a Database Connection Pool (DBCP) connection broker. In a nutshell, define all your Tomcat database resources in the pool (including login credentials) and let your apps reference to them.


Important!

Delete all (naming?) jars from {RED5_HOME}/WEB-INF/lib/ that are already present in {TOMCAT_HOME}/common/lib/ These are probably: `naming-factory-.jar` and `naming-resources-.jar`.

When having these jars in both places, the application will see a different JNDI environment than the appserver will. This is appearently not ok and you will get into problems: 'JNDI Name java:comp is not bound in this Context'.

If you use Tomcat 6, `{TOMCAT_HOME}/lib/tomcat-dbcp.jar` contains the above mentioned jars. So, also for Tomcat 6, get rid of the naming jars in {RED5_HOME}/WEB-INF/lib/


Step 1: Define a database resource

Add the following <Context> tag to {TOMCAT_HOME}\conf\server.xml

<Server>
  <Service name="Catalina">
    <Engine defaultHost="localhost" name="Catalina">
      <Host appBase="webapps" name="localhost">

       <Context path="/red5-0.6rc1">
         <Resource
           name="jdbc/your_ref_name"
           type="javax.sql.DataSource"
           url="jdbc:mysql://yourmysqlhost.domain.com/your_database_name?autoReconnect=true"
           username="your_username"
           password="your_password"
           driverClassName="com.mysql.jdbc.Driver"
           maxIdle="2"
           maxWait="5000"
           maxActive="4"/>
         </Context>

       </Host>
     </Engine>
   </Service>
 </Server>

Step 2: Hook up your app

Place the following somewhere between the <web-app> tags of the file {RED5_HOME}\WEB-INF\web.xml

<resource-ref>
  <description>DB Connection</description>
  <res-ref-name>jdbc/your_ref_name</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

Make sure <res-ref-name> matches the <Resource name=""> from Step 1!

Step 3: (Red5) java code

import java.sql.*;
import javax.naming.*;
import javax.sql.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class Application extends ApplicationAdapter implements IPendingServiceCallback, IStreamAwareScopeHandler {
  private static final Log log = LogFactory.getLog(Application.class);
  private DataSource dataSource;


  @Override
  public boolean appStart(IScope scope) {
    // init your handler here

    try {
        Context init = new InitialContext();
        Context ctx = (Context) init.lookup("java:comp/env");
        dataSource = (DataSource) ctx.lookup("jdbc/your_database_name");
        log.debug("JNDI OK!!!");
      }
      catch (NamingException ex) { // Error handling here
       log.error("JNDIException: " + ex.getMessage());
      }

     Connection con = null;    
     try {
         synchronized (dataSource) {
           con = dataSource.getConnection();
         }
         PreparedStatement pstmt = con.prepareStatement("INSERT INTO log_chatroom (message) VALUES (?)");
         pstmt.setString(1, "This is a test!");
         ResultSet results = pstmt.executeQuery();
         if (results != null) results.close(); // You can loop through records if you use a SELECT query
         if (pstmt != null) pstmt.close();
         if (con != null) con.close();
     }
     catch (Exception ex)
     { // Exception handling here
     }          
     return true;
  }
}

Using Mysql

To perform simple queries have a look at the docu of Connection. For simple Update queries which don't provide any data call:

 Statement stmt = conn.createStatement();
 stmt.execute("SOME SQL QUERY");

If you want to fetch some DB-data use:

 Statement  stmt = conn.createStatement();
 ResultSet result = stmt.executeQuery("SOME SQL QUERY");
 // if you dont loop over the result set, make sure you call result.next() first
 // otherwise you'll end up with an empty set!
 while (result.next()) {
      // youre code comes here
      // getXXX use to retreive the Data from a resultset, getInt, getString and so on
      // getXXX can be used with the columnname or the column position (int)
      System.out.println(result.getString("my_mysql_columnName"));
 }
Personal tools