31 Ekim 2017 Salı

HttpServletRequestWrapper Sınıfı

Giriş
HttpServletRequest'i değiştiremeyiz ancak sarmalayarak farklı bir davranış elde edebiliriz.

getHeaders metodu
Şöyle yaparız
public class MyRequestWrapper extends HttpServletRequestWrapper{

  public MyRequestWrapper(HttpServletRequest request){
    super(request);
  }

  @Override 
  public String getHeaders(String name){
    if(name.equals("X-Forwarded-Proto"){
      return "xyz";
    }
    else{
      return ((HttpServletRequest)getRequest()).getHeaders(name);
    }
  }
}
Kullanım
Şöyle yaparız
public class MyFilter implements Filter{

  @Override
  public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {

    chain.doFilter(new MyRequestWrapper((HttpServletRequest)request), response);
  }
}

30 Ekim 2017 Pazartesi

web.xml

Giriş
Bu dosyanın bulunduğu dizin şöyle
/usr/share/tomcat/webapps/<WEBAPP-NAME>/WEB-INF/web.xml
web-app tag
Bu dosyada servlet spec'inden hangisini kullanacağımızı belirtiyoruz.
Örnek
2.5 için şöyle yaparız
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">
  ...
</web-app>
Örnek
3.0 içinse şöyle yaparız.
<web-app 
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">
context-param tag
Bu parametre servlet ayağa kalkarken okunuyor ve ServletContext arayüzüne yerleşiyor. How to get context-param value in java? sayfasında konuyla ilgili örnek var. Spring gibi bazı çatı yapıları belli isimdeki parametrelerin kullanılmasını gerektiriyor. Örneğin contextConfigLocation

<!-- Configure spring -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/applicationContext.xml
        /WEB-INF/applicationContext-security.xml
        /WEB-INF/applicationContext-integration.xml
    </param-value>
</context-param>

Bir başka örnekte ise xml dosyasına tam path te verilmeden başlatılıyor.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:beans.xml</param-value>
</context-param>

display-name
Yönetim ekranında gösterilen servlet ismi. Şöyle yaparız. Servlete http isteği ile erişmek için bu isim değil war dosyasının ismi kullanılı.r
<display-name>TomcatRestExample</display-name>
filter tag
Uygulamaya sadece belli IP'lerin erişmesini istersek şöyle yaparız.
<filter>
  <filter-name>Remote Address Filter</filter-name>
  <filter-class>org.apache.catalina.filters.RemoteAddrFilter</filter-class>
  <init-param>
    <param-name>allow</param-name>
    <param-value>127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>Remote Address Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
listener tag
ServletContextListener sınıfları bu tag ile tanıtılıyor.

session-config
30 dakika tanımlamak için şöyle yaparız.
<session-config>
  <session-timeout>30</session-timeout>     
  <tracking-mode>COOKIE</tracking-mode>
</session-config>
servlet tag
Servlet sınıflarını tanımlıyor.
Örnek
Şöyle  yaparız:
<servlet>
   <servlet-name>Faces Servlet</servlet-name>
   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>
Örnek
Şöyle yaparız.
<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">

  <display-name>TomcatRestExample</display-name>

  <servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>...</servlet-class>
    <init-param>
      <param-name>...</param-name>
      <param-value>...</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/maven/*</url-pattern>
  </servlet-mapping>

</web-app>
servlet-mapping tag
Yukarıda tanımlanan servlet sınıfını ile servletin hizmet edeceği url adreslerini eşleştiriyor. Eşleştirme için servlete verilen ismin kullanıldığına dikkat etmek lazım.

Örnek
Şöyle yaparız.
<servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
Servlet mapping kuralları şöyle. Bu kurallardan sadece '/' verileni ilginç.

  • A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
  • A string beginning with a ‘*.’ prefix is used as an extension mapping.
  • The empty string ("") is a special URL pattern that exactly maps to the application's context root, i.e., requests of the form  http://host:port/<contextroot>/. In this case the path info is ’/’ and the servlet path and context path is empty string (““).
  • A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
  • All other strings are used for exact matches only
welcome-file-list tag
Uygulama ilk açılırken gösterilecek sayfayı tanımlıyor. Şöyle yaparız:
<welcome-file-list>
  <welcome-file>index.xhtml</welcome-file>
</welcome-file-list>

DataSource Arayüzü

Giriş
Şu satırı dahil ederiz.
import javax.sql.DataSource;
Bu sınıf DriverManager  ile aynı işi görür. Açıklaması şöyle
The DataSource interface is implemented by a driver vendor. There are three types of implementations:
Basic implementation -- produces a standard Connection object
Connection pooling implementation -- produces a Connection object that will automatically participate in connection pooling. This implementation works with a middle-tier connection pooling manager.
Distributed transaction implementation -- produces a Connection object that may be used for distributed transactions and almost always participates in connection pooling. This implementation works with a middle-tier transaction manager and almost always with a connection pooling manager.
constructor - JNDI
Uygulama sunucusunu kullanarak şöyle yaparız.
Context context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/myDB");
Şöyle yaparız.
DataSource ds = (DataSource) new InitialContext().lookup("jdbc/myDS");
constructor - C3P0
Şu satırı dahil ederiz.
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-c3p0</artifactId>
  <version>4.2.20.Final</version>
</dependency>

<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
  <groupId>c3p0</groupId>
  <artifactId>c3p0</artifactId>
  <version>0.9.1.2</version>
</dependency>
Bazı değişkenler şöyle
minPoolSize=10
maxPoolSize=50
maxStatements=50
idleConnectionTestPeriod=3600
acquireIncrement=5
maxIdleTime=600
numHelperThreads=6
unreturnedConnectionTimeout=3600
maxIdleTimeExcessConnections=600
Şöyle yaparız.
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
cpds.setUser("swaldman");
cpds.setPassword("test-password");

// the settings below are optional -- c3p0 can work with defaults
cpds.setMinPoolSize(5);
cpds.setAcquireIncrement(5);
cpds.setMaxPoolSize(20);

// The DataSource cpds is now a fully configured and usable pooled DataSource 
constructor - DBCP
Şöyle yaparız.
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver")
ds.setUsername("scott");
ds.setPassword("tiger");
ds.setUrl(connectURI);
...
Connection conn = ds.getConnection();
constructor - MySql
Maven için şöyle yaparız.
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
</dependency>
MySql JDBC sürücüsünün ismi MySQL Connector/J'dir. Bu jar dosyasının CLASSPATH içinde olması gerekir. Şöyle yaparız.
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUser("scott");
dataSource.setPassword("tiger");
dataSource.setServerName("myDBHost.example.org");
constructor - Oracle
OracleDataSource Sınıfı yazısına taşıdım.

constructor - Oracle Universal Connection Pool
Açıklaması şöyle
Prior to 12c (i.e., 12.1.0.1.0), UCP could work with any version of Oracle JDBC driver. With the new pool, UCP 12.1.0.2, it is dependent on Oracle JDBC driver 12.1.0.2.
Şöyle yaparız.
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();

pds.setURL(...);
pds.setUser(...);
pds.setPassword(...);
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");

//Setting pool properties
pds.setInitialPoolSize(5);
pds.setMinPoolSize(5);
pds.setMaxPoolSize(20);

Connection conn = pds.getConnection();
Şöyle yaparız.
int usedConnectionCount = pds.getBorrowedConnectionsCount();
int availableConnectionCotun = pds.getAvailableConnectionsCount();
constructor - postgresql
Maven için şöyle yaparız.
<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>9.4-1200-jdbc4</version>
</dependency>
constructor - tomcat
Açıklaması şöyle. Tomcat'in DataSource arayüzünü kullanan ve yine ismi DataSource olan (bence talihsiz bir seçim) sınıfıdır.
The JDBC Connection Pool org.apache.tomcat.jdbc.pool is a replacement or an alternative to the Apache Commons DBCP connection pool.
Örnek
Şöyle yaparız.
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;


private static final String USERNAME = "root";
private static final String PASSWORD = "";
private static final String DATABASE_NAME = "store_db";

PoolProperties p = new PoolProperties();
p.setUrl("jdbc:mysql://localhost:3306/" + DATABASE_NAME);
p.setDriverClassName("com.mysql.jdbc.Driver");
p.setUsername(USERNAME);
p.setPassword(PASSWORD);

DataSource ds = new DataSource();
ds.setPoolProperties (p);
Örnek
Şöyle yaparız. Sınıfın aslında milyon tane ayarı var :)
PoolProperties pool = new PoolProperties();
pool.setUrl(dbUrl);   // jdbc:sqlserver://hostname:port;databaseName=*** 
pool.setDriverClassName(provider); //com.microsoft.sqlserver.jdbc.SQLServerDriver
pool.setUsername(userName);
pool.setPassword(password);
pool.setJmxEnabled(true);
pool.setTestWhileIdle(false);
pool.setTestOnBorrow(true);
pool.setValidationQuery("SELECT 1");
pool.setTestOnReturn(false);
pool.setValidationInterval(validationInterval);  // 30000 MS 
pool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); // 30000 MS 
pool.setMaxActive(maxpoolSize); // 100
pool.setInitialSize(initialSize);  //10
pool.setMaxWait(maxWait); // 15000 MS
pool.setRemoveAbandonedTimeout(removeAbandonedTimeout);
pool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  // 60
pool.setMaxIdle(maxIdle);  // 50
pool.setMinIdle(minIdle);  // 10 
pool.setLogAbandoned(true);
pool.setRemoveAbandoned(true);
pool.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" +
  "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");

dataSource = new DataSource();
dataSource.setPoolProperties(pool);
getConnection metodu
Örnek
Şöyle yaparız.
Connection con = dataSource.getConnection();
Örnek
Şöyle yaparız.
try (Connection connnection = dataSource.getConnection()) {
  // use the connection
  connection.commit();
}