tag:blogger.com,1999:blog-12567882200205569502024-03-14T06:22:39.086-07:00Sergej Sizov - Software EngineeringWriting code in Java, Ruby and JavaScriptSergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-1256788220020556950.post-14394562024492022222016-11-06T11:33:00.000-08:002016-11-06T11:34:26.818-08:00Easy password hash migration from MD5 to BCrypt.<div dir="ltr" style="text-align: left;" trbidi="on">
Many legacy production systems still use non-salted MD5 function for password hashing. These hashes are usually stored in the database and used for user authentication. The problem is that non-salted MD5 hash is no more secure today. There are so-called rainbow tables (precomputed MD5 hashes for word dictionaries) that can be used for easy reverse lookup.<br />
<a name='more'></a><br />
<br />
Nowadays it is recommended to use BCrypt hashing function that incorporates a salt to protect against rainbow table attacks. Even if your database is compromised and leaked, it is not possible (or at least difficult for now) to decrypt users' passwords.<br />
<i><br /></i>
<i>The obvious way to migrate to BCrypt is to update password hash on user sign in. Also, there should be some flag that indicates if password hash is already migrated to BCrypt or not. For non-migrated accounts we need to reset passwords and force users to change their password. </i><br />
<br />
Is there any better and painless way, so that we will not bother users with password change? And the answer is - <b>double hashing</b>. Let's hash our already hashed password (with MD5) with BCrypt once more.<br />
<br />
Our migrated database will contain values after the following transformation:<br />
<br />
<pre>plaintext -> MD5 -> BCrypt
</pre>
<br />
New passwords will be double hashed using the following function:<br />
<br />
<pre>BCrypt( MD5( 'PlainPassword' ) )
</pre>
<br />
The following example is for PostgreSQL database. You need to install <b>pgcrypto</b> extension to enable support for BCrypt:<br />
<br />
<pre>postgres=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
postgres=# SELECT <b>crypt</b>(<b>md5</b>('YourPasswordGoesHere'), <b>gen_salt</b>('bf', 10));
crypt
--------------------------------------------------------------
$2a$10$y8jgt.GoqX8w0ScGlMYsrOrgWYyARuO9FjvSUAx7mnEjY3b1E6NLi
</pre>
<br />
<br />
The following snippet shows password verification in Java with DigestUtils and jBCrypt:<br />
<br />
<pre>String hashed = Bcrypt.<b>hashpw</b>(DigestUtils.<b>md5Hex</b>(password), Bcrypt.<b>gensalt</b>(10));
boolean password_valid = Bcrypt.<b>checkpw</b>(user.getPasswordHash(), hashed));
</pre>
</div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-2551855855660704062016-06-05T04:11:00.000-07:002016-06-05T04:11:07.637-07:00Alexander Goldstein's Each! Pattern<div dir="ltr" style="text-align: left;" trbidi="on">
<pre><b>class</b> Array
<b>def</b> each!
<b>while</b> count > 0
<b>yield</b>(shift)
<b>end</b>
<b>end</b>
<b>end</b>
</pre>
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-46684280300444448882015-10-22T09:43:00.000-07:002015-10-22T09:43:02.078-07:00SelectionSort in Java<div dir="ltr" style="text-align: left;" trbidi="on">
<pre> public static void selectionsort(int[] A) {
for (int i = 0; i < A.length; i++) {
int min = i;
for (int j = i+1; j < A.length; j++) {
if (A[j] < A[min]) {
min = j;
}
}
swap(A, i, min);
}
}
public static void swap(int[] A, int i, int j) {
int temp = A[j];
A[j] = A[i];
A[i] = temp;
}
</pre>
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-55714815586779812762015-10-22T09:42:00.001-07:002015-10-22T09:42:23.740-07:00InsertionSort in Java<div dir="ltr" style="text-align: left;" trbidi="on">
<pre> public static void insertionsort(int[] A) {
for (int i = 1; i < A.length; i++) {
for (int j = i; j > 0 && A[j] < A[j - 1]; j--) {
swap(A, j, j - 1);
}
}
}
public static void swap(int[] A, int i, int j) {
int temp = A[j];
A[j] = A[i];
A[i] = temp;
}
</pre>
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-71168606966451749702015-10-22T09:41:00.001-07:002015-10-22T09:41:36.080-07:00MergeSort in Java<div dir="ltr" style="text-align: left;" trbidi="on">
<pre> public static void mergesort(int[] A) {
int[] aux = new int[A.length];
mergesort(A, aux, 0, A.length-1);
}
private static void mergesort(int[] A, int[] aux, int lo, int hi) {
if (lo >= hi) return;
int m = (lo+hi) / 2;
mergesort(A, aux, lo, m);
mergesort(A, aux, m+1, hi);
merge(A, aux, lo, m, hi);
}
private static void merge(int[] A, int[] aux, int lo, int m, int hi) {
int i = lo;
int j = m+1;
for (int k=lo; k <= hi; k++) {
if (i > m) {
aux[k] = A[j];
j++;
} else if (j > hi) {
aux[k] = A[i];
i++;
} else if (A[j] < A[i]) {
aux[k] = A[j];
j++;
} else {
aux[k] = A[i];
i++;
}
}
for (int k=lo; k <= hi; k++) {
A[k] = aux[k];
}
}
</pre>
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-53207729384174136802015-10-22T06:37:00.001-07:002015-10-22T06:37:22.587-07:00QuickSort in Java<div dir="ltr" style="text-align: left;" trbidi="on">
<pre> public static void quicksort(int[] A) {
quicksort(A, 0, A.length-1);
}
private static void quicksort(int[] A, int lo, int hi) {
if (lo >= hi) return;
int p = partition(A, lo,hi);
quicksort(A, lo, p-1);
quicksort(A, p+1, hi);
}
private static int partition(int[] A, int lo, int hi) {
int i = lo+1;
int j = hi;
while (i <= j) {
while (A[i] < A[lo]) {
i++;
if (i > hi) break;
}
while (A[j] > A[lo]) {
j--;
}
if (i <= j) {
swap(A, i, j);
i++;
j--;
}
}
swap(A, lo, j);
return j;
}
public static void swap(int[] A, int i, int j) {
int temp = A[j];
A[j] = A[i];
A[i] = temp;
}
</pre>
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-66103846617852463032015-01-03T05:57:00.000-08:002015-01-03T08:03:23.108-08:00Python socksipy: SFTP with Paramiko via SOCKS proxy<div dir="ltr" style="text-align: left;" trbidi="on">
I use Paramiko library to access SFTP servers in Python. Paramiko is easy to use, provides programmer with rich functionality, but it does not support proxy servers out of the box. There is a small library <b>socksipy</b> that can be easily integrated with Paramiko.<br />
<br />
<br />
<a name='more'></a><br />
<h3 style="text-align: left;">
Setting up a connection with Paramiko</h3>
<br />The following source code sets up connection to remote SFTP server:<br />
<pre>import paramiko
try:
ssh = paramiko.SSHClient()
logger.debug('Attempting SFTP connection')
ssh.connect(hostname='sftp.example.com')
sftp = ssh.open_sftp()
logger.debug('Connected to SFTP')
except Exception as e:
logger.error('Connection failed: %s', str(e))
sys.exit('Could not connect')
</pre>
<br />
<h3 style="text-align: left;">
Configuring SOCKS proxy</h3>
<br />Socksipy can be downloaded from http://socksipy.sourceforge.net<br />
<br />
The following is the socksipy proxy object configuration:<br />
<pre>import socks
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, 'socks.example.com')
</pre>
<br />
<b>Syntax</b>: <span style="font-family: Courier New, Courier, monospace;">setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]])</span><br />
<br />
<br />
<h3 style="text-align: left;">
Setup Paramiko to communicate via SOCKS proxy</h3>
<br />We should replace paramiko socket with socksipy object:<br />
<pre>import paramiko
import socks
logger.debug('Using SOCKS proxy')
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, 'socks.example.com')
<b>paramiko.client.socket.socket = socks.socksocket</b>
try:
ssh = paramiko.SSHClient()
logger.debug('Attempting SFTP connection')
ssh.connect(hostname='sftp.example.com')
sftp = ssh.open_sftp()
logger.debug('Connected to SFTP')
except Exception as e:
logger.error('Connection failed: %s', str(e))
sys.exit('Could not connect')
</pre>
<br />
<br />
More info about socksipy can be found here: http://socksipy.sourceforge.net/readme.txt
<br /><br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-35984771056038437752014-07-16T04:18:00.001-07:002014-07-16T04:19:53.643-07:00Kerberos Windows configuration for Java 7<div dir="ltr" style="text-align: left;" trbidi="on">
After migrating to Java 7, our Java client application was unable to authenticate via Kerberos on Windows. If you have the same problem, the following configuration may help you solve it. There is a key <b>allowtgtsessionkey</b> in Windows registry that allows client application to decrypt session key of Kerberos <b>Ticket Granting Ticket</b> (TGT).<br />
<br />
<a name='more'></a><br />
<h3 style="text-align: left;">
Windows Registry configuration</h3>
Depending on the version of Windows you use, this registry key should be created in the following Registry path.<br />
<br />
<h4 style="text-align: left;">
Windows XP</h4>
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\<br />
REG_DWORD name: allowtgtsessionkey<br />
Value: 1<br />
<br />
<h4 style="text-align: left;">
Windows 2003 Server, Vista, 7, 8, etc.</h4>
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters<br />
REG_DWORD name: allowtgtsessionkey<br />
Value: 1<br />
<br />
<br />
<h3 style="text-align: left;">
Default realm not found</h3>
Another problem that occurred (not sure if it is connected to Java 7) was missing default realm.<br />
<br />
Find your <b>krb5.ini</b> file and add the following section if it is missing<br />
<br />
<b>[libdefaults]</b><br />
<b>default_realm = EUROPE.EXAMPLE.COM</b><br />
[realms]<br />
// KDC configuration for realms<br />
EUROPE.EXAMPLE.COM = {<br />
kdc = eudc01.example.com<br />
}<br />
<br />
<br />
<br />
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-87741527170106799322013-02-16T08:03:00.000-08:002013-02-16T08:03:29.678-08:00Spring Security and Http Basic Authentication<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
This article will show you how to use <b>Spring Security</b> to protect your web application with <b>Http Basic</b> Authentication.<br />
<br />
<br />
<a name='more'></a><br />
Our application will require that users will authenticate themeselves with Http Basic Authentication. Unauthorized users will get <b>401 UNAUTHORIZED</b> response and will have to authenticate themselves with login and password.<br />
<br />
I expect that your application is already using Spring Framework and Maven. So, to start using Spring Security we need to add these maven dependencies:<br />
<br />
<pre class="brush: xml"><dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.3.RELEASE</version>
</dependency></pre>
<br />
We need to add <b>Spring Security Filter</b> to web.xml configuration so that it will intercept all HTTP requests.<br />
<br />
<pre class="brush: xml"><filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</pre>
<br />
Then we need to implement a <b>UserService </b>that checks that the user exists (e.g. in a database).<br />
<br />
<pre class="brush: java">public class UserServiceImpl implements UserService {
private Map<String, UserDetails> users = new HashMap<String, UserDetails>();
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (users.containsKey(username)) {
return users.get(username);
}
throw new UsernameNotFoundException("User " + username + " not found");
}
}</pre>
<div>
<br /></div>
<div>
<br /></div>
The next step is to implement a <b>BasicAuthenticationEntryPoint </b>that would tell users that they have to authenticate in order to access this application.<br />
<br />
<pre class="brush: java">public class VozisBasicAuthenticationEntryPoint extends
BasicAuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.addHeader("WWW-Authenticate", "Basic realm=\"" +
getRealmName() + "\"");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED +
" - " + authException.getMessage());
}
}
</pre>
<br />
Now we have all components that we need, let's integrate them together. Below is the example of <b>security.xml</b> configuration:<br />
<br />
<pre class="brush: xml"><beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd ">
<global-method-security secured-annotations="enabled" />
<http auto-config="false" create-session="stateless">
<http-basic entry-point-ref="authenticationEntryPoint" />
</http>
<beans:bean id="authenticationEntryPoint"
class="com.blogspot.vozis.security.VozisBasicAuthenticationEntryPoint">
<beans:property name="realmName" value="Vozis" />
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userService" />
</authentication-manager>
<beans:bean id="userService" class="com.blogspot.vozis.security.UserServiceImpl" />
</beans:beans>
</pre>
<div>
<br /></div>
<br />
<br />
<br /></div>
</div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com2tag:blogger.com,1999:blog-1256788220020556950.post-70990748838220314342013-02-16T06:38:00.000-08:002013-02-16T06:38:21.400-08:00Log4jdbc: Logging JDBC activity and SQL queries<div dir="ltr" style="text-align: left;" trbidi="on">
In an application that frequently queries a database it is important to know what is happening now, how often this or that query occurs and how long it takes to get result. <b>Log4jdbc</b> allows to log database activity e.g. SQL queries, processing time, result sets, connection usage.<br />
<div>
<a name='more'></a><br /></div>
<div>
<b>Log4jdbc</b> creates a <b>JDBC</b> <b>Proxy</b>. Every SQL request is intercepted, logged with <b>SLF4J</b> and passed back to real JDBC driver. </div>
<div>
<br /></div>
<div>
So why and when do we need to log database activity? Many ORM frameworks e.g. Hibernate allow you to show SQL when running in debug mode.<br />
<br />
To see what Hibernate is doing with your database, just add these parameters to your Hibernate configuration:<br />
<br />
<pre class="brush: xml"><property name="show_sql">true</property>
<property name="format_sql">true</property>
</pre>
<br />
The following output will be generated by Hibernate logger:<br />
<br />
<pre>DEBUG org.hibernate.SQL - select deliveryre0_.id as id1_, deliveryre0_.callback_reference_id as callback2_1_, deliveryre0_.client_correlator as client3_1_, deliveryre0_.client_id as client4_1_, deliveryre0_.created as created1_, deliveryre0_.last_status_change as last6_1_, deliveryre0_.status as status1_, deliveryre0_.sender_address as sender8_1_ from delivery_report_notification deliveryre0_ where deliveryre0_.client_id=? and deliveryre0_.client_correlator=?
</pre>
<br /></div>
<div>
The disadvantage of these debug records is that they show PreparedStatements with placeholders instead of real values. It is certainly possible to debug parameter bindings in Hibernate, but the output is unnecessary verbose:</div>
<br />
<pre>Hibernate: INSERT INTO table (ID, DATE, PRICE) VALUES (?, ?, ?)
10:13:05,129 DEBUG IntegerType:133 - binding '1' to parameter: 1
10:13:05,133 DEBUG DateType:133 - binding '14 October 2012' to parameter: 2
10:13:05,134 DEBUG FloatType:133 - binding '3.75' to parameter: 3
</pre>
<br />
The output generated by Log4jdbc is more useful, it show a real query that is passed into database with real values:<br />
<br />
<pre>INFO jdbc.sqltiming - select deliveryre0_.id as id1_, deliveryre0_.callback_reference_id as callback2_1_, deliveryre0_.client_correlator as client3_1_, deliveryre0_.client_id as client4_1_, deliveryre0_.created as created1_, deliveryre0_.last_status_change as last6_1_, deliveryre0_.status as status1_, deliveryre0_.sender_address as sender8_1_ from delivery_report_notification deliveryre0_ where deliveryre0_.client_id=2 and deliveryre0_.client_correlator='ALPHABETA' {executed in 1 msec}</pre>
<br />
This was an example of the jdbc.sqltiming logger. Log4jdbc has several loggers that can be used e.g. to track connection usage:<br />
<br />
<ul style="text-align: left;">
<li><b>jdbc.sqlonly</b> - Logs only SQL. SQL executed within a prepared statement is automatically shown with it's bind arguments replaced with the data bound at that position, for greatly increased readability.</li>
<li><b>jdbc.sqltiming</b> - Logs the SQL, post-execution, including timing statistics on how long the SQL took to execute.</li>
<li><b>jdbc.audit</b> - Logs ALL JDBC calls except for ResultSets. This is a very voluminous output, and is not normally needed unless tracking down a specific JDBC problem.</li>
<li><b>jdbc.resultset</b> - Even more voluminous, because all calls to ResultSet objects are logged.</li>
<li><b>jdbc.connection</b> - Logs connection open and close events as well as dumping all open connection numbers. This is very useful for hunting down connection leak problems.</li>
</ul>
<br />
<b>Logback configuration</b><br />
<br />
<pre class="brush: xml"><logger name="jdbc.sqlonly" level="OFF" additivity="false" />
<logger name="jdbc.sqltiming" level="INFO" additivity="false">
<appender-ref ref="DATABASE_LOG_FILE" />
</logger>
<logger name="jdbc.audit" level="OFF" additivity="false" />
<logger name="jdbc.resultset" level="OFF" additivity="false" />
<logger name="jdbc.connection" level="OFF" additivity="false" />
<logger name="jdbc.resultsettable" level="OFF" additivity="false" />
<logger name="log4jdbc.debug" level="OFF" additivity="false" /></pre>
<br />
<br />
Log4jdbc is not available on Maven central repository, so you have to download it manually. Log4jdbc is available on Google Code at <a href="http://code.google.com/p/log4jdbc/" target="_blank">http://code.google.com/p/log4jdbc/</a>. You can download its source codes or jars for JDBC 3 or 4.<br />
<div>
<br />
<br />
<b>Good news</b><br />
<br />
There is an experimental fork called <b>log4jdbc-remix</b>, that solves some of the Log4jdbc problems. It is available on Maven central repository:<br />
<br />
<pre class="brush: xml"><dependency>
<groupId>org.lazyluke</groupId>
<artifactId>log4jdbc-remix</artifactId>
<version>0.2.7</version>
</dependency>
</pre>
<div>
<br /></div>
<br />
Also you can use it in Spring as a datasource.<br />
<br />
<pre class="brush: xml"><bean id="dataSourceSpied" class="...">
<property name="driverClass" value="${datasource.driverClassName}"/>
<property name="jdbcUrl" value="${datasource.url}"/>
<property name="user" value="${datasource.username}"/>
<property name="password" value="${datasource.password}"/>
...
</bean>
<bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource">
<constructor-arg ref="dataSourceSpied" />
</bean>
</pre>
<br />
<b>Log4jdbc-remix</b> is available on Google Code at <a href="http://code.google.com/p/log4jdbc-remix/">http://code.google.com/p/log4jdbc-remix/</a><br />
<br />
<br />
<br /></div>
<div>
<br /></div>
<div>
</div>
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com2tag:blogger.com,1999:blog-1256788220020556950.post-55513560416153438282013-02-15T05:42:00.000-08:002013-02-15T05:47:31.933-08:00RestTemplate and HttpClient 4.1 configuration<div dir="ltr" style="text-align: left;" trbidi="on">
This example shows how to configure <b>Spring RestTemplate</b> with Apache <b>HttpClient</b> 4.1 as a transport.<br />
<br />
<a name='more'></a>In this example we will configure the following parameters:<br />
<br />
<ul style="text-align: left;">
<li>connection timeout</li>
<li>read timeout</li>
<li>maximum connections (per host)</li>
<li>maximum connections (total)</li>
</ul>
<br />
Also, we will set up <b>Http Basic Authentication</b> using login and password.<br />
<br />
We are going to use JavaConfig <b>@Configuration</b> class, that has all the parameters set from properties using @Value annotations.<br />
<br />
<pre class="brush: java">@Configuration
public class RestClientConfig {
@Value("${rest.client.login}")
private String restClientLogin;
@Value("${rest.client.password}")
private String restClientPassword;
@Value("${rest.client.connectionTimeoutMillis}")
private int restClientConnectionTimeoutMillis;
@Value("${rest.client.readTimeoutMillis}")
private int restClientReadTimeoutMillis;
@Value("${rest.client.maxConnectionsPerHost}")
private int restClientMaxConnectionsPerHost;
@Value("${rest.client.maxTotalConnections}")
private int restClientMaxTotalConnections;
// ...
}</pre>
<br />
Lets define HttpClient @Bean by creating new <b>PoolingClientConnectionManager</b> and configuring maxConnectionsPerHost and maxTotalConnections.<br />
<br />
<pre class="brush: java">@Bean
public HttpClient getHttpClient() {
final PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(restClientMaxConnectionsPerHost);
connectionManager.setMaxTotal(restClientMaxTotalConnections);
final DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager);
// ...
return httpClient;
}</pre>
<br />
Then we need to configure <b>ClientHttpRequestFactory</b> that allows to define read and connection timeouts.<br />
<br />
<pre class="brush: java">@Bean
public ClientHttpRequestFactory getClientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(getHttpClient());
factory.setConnectTimeout(restClientConnectionTimeoutMillis);
factory.setReadTimeout(restClientReadTimeoutMillis);
return factory;
}</pre>
<br />
Now we can create <b>RestTemplate</b> @Bean<br />
<br />
<pre class="brush: java">@Bean
public RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
return restTemplate;
}</pre>
<br />
Now we need to configure Http Basic Authentication. To do Basic Authentication we need to add <b>Authentication: Basic</b> header to HTTP request. We can do it by registering a <b>HttpRequestInterceptor</b> that would add the header to every request.<br />
<br />
<pre class="brush: java">public class HttpBasicAuthInterceptor implements HttpRequestInterceptor {
private UsernamePasswordCredentials creds;
public HttpBasicAuthInterceptor(UsernamePasswordCredentials creds) {
this.creds = creds;
}
@Override
public void process(HttpRequest request, HttpContext context)
throws HttpException, IOException {
request.addHeader(new BasicScheme().authenticate(creds, request, context));
}
}</pre>
<br />
Register <b>HttpRequestInterceptor</b> in HttpClient:<br />
<br />
<pre class="brush: java">HttpRequestInterceptor interceptor = new HttpBasicAuthInterceptor(new UsernamePasswordCredentials(restClientLogin, restClientPassword));
httpClient.addRequestInterceptor(interceptor);</pre>
<br />
<br />
<b>Full source code:</b><br />
<br />
<pre class="brush: java">@Configuration
public class RestClientConfig {
@Value("${rest.client.login}")
private String restClientLogin;
@Value("${rest.client.password}")
private String restClientPassword;
@Value("${rest.client.connectionTimeoutMillis}")
private int restClientConnectionTimeoutMillis;
@Value("${rest.client.readTimeoutMillis}")
private int restClientReadTimeoutMillis;
@Value("${rest.client.maxConnectionsPerHost}")
private int restClientMaxConnectionsPerHost;
@Value("${rest.client.maxTotalConnections}")
private int restClientMaxTotalConnections;
@Bean
public HttpClient getHttpClient() {
final PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(restClientMaxConnectionsPerHost);
connectionManager.setMaxTotal(restClientMaxTotalConnections);
final DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager);
HttpRequestInterceptor interceptor = new HttpBasicAuthInterceptor(new UsernamePasswordCredentials(restClientLogin, restClientPassword));
httpClient.addRequestInterceptor(interceptor);
return httpClient;
}
@Bean
public ClientHttpRequestFactory getClientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(getHttpClient());
factory.setConnectTimeout(restClientConnectionTimeoutMillis);
factory.setReadTimeout(restClientReadTimeoutMillis);
return factory;
}
@Bean
public RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
return restTemplate;
}
}
public class HttpBasicAuthInterceptor implements HttpRequestInterceptor {
private UsernamePasswordCredentials creds;
public HttpBasicAuthInterceptor(UsernamePasswordCredentials creds) {
this.creds = creds;
}
@Override
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
request.addHeader(new BasicScheme().authenticate(creds, request, context));
}
}</pre>
<div>
<br /></div>
<br />
<br />
<br />
<br /></div>
Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com1tag:blogger.com,1999:blog-1256788220020556950.post-27818355943325423492012-07-02T10:11:00.001-07:002012-07-11T13:26:33.142-07:00Spring MVC and Velocity WebApp<div dir="ltr" style="text-align: left;" trbidi="on">
This tutorial shows how to use <b>Velocity templates</b> with <b>Spring MVC</b>. Velocity is more flexible templating engine than JSP/JSTL standard templates. We will create a simple application that contains 2 pages: list and detail. These pages will have common layout. <br />
<br />
<a name='more'></a><span style="font-size: large;">Start with an empty Maven web application </span><br />
<br />
We need to add Spring and Velocity dependencies to our pom.xml file:<br />
<br />
<pre class="brush: xml"> <dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
</pre>
<br />
<br />
<br />
Web Application will be deployed to Jetty Web Container. Add the following plugin to plugins section of pom.xml:<br />
<br />
<pre class="brush: xml"> <plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.16</version>
<configuration>
<contextPath>/</contextPath>
<scanTargets>
<scanTarget>target/classes/</scanTarget>
</scanTargets>
<scanIntervalSeconds>5</scanIntervalSeconds>
</configuration>
</plugin>
</pre>
<br />
To start the application call <b>mvn jetty:run</b><br />
<br />
The application will be available on http://127.0.0.1:8080/. When you open this address with a browser you will see just a Hello World message from index.jsp, indicating that empty application was successfully deployed. <br />
<br />
<b>Note:</b> You may use any web container you like (e.g. Tomcat). I prefer Jetty because it is very fast and light-weight.<br />
<br />
<br />
<span style="font-size: large;">Dummy data model</span><br />
<br />
Our application will be showing a list of <b>Feeds</b> with link to detail.<br />
<br />
Entity <b>Feed</b> contains <b>Id </b>and <b>Title</b>. <br />
<br />
<pre class="brush: java">package com.blogspot.vozis.springvelocity.data;
/**
* Feed
* @author sergej.sizov
*/
public class Feed {
private Integer id;
private String title;
public Feed(Integer id, String title) {
this.id = id;
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}</pre>
<br />
FeedService is a provider of Feeds. It has 2 methods: getFeedById() and getFeeds().<br />
<br />
<pre class="brush: java">package com.blogspot.vozis.springvelocity.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
/**
* Feed Service
* @author sergej.sizov
*/
@Service
public class FeedService {
private Map<Integer, Feed> storage = new HashMap<Integer, Feed>();
public FeedService() {
storage.put(1, new Feed(1, "Spring Tutorial"));
storage.put(2, new Feed(2, "Velocity Tutorial"));
storage.put(3, new Feed(3, "Java Tutorial"));
}
public Feed getFeedById(Integer id) {
return storage.get(id);
}
public List<Feed> getFeeds() {
List<Feed> list = new ArrayList<Feed>();
list.addAll(storage.values());
return list;
}
}
</pre>
<br />
<span style="font-size: large;">Spring Context Configuration</span><br />
<br />
Now it is time to configure Spring framework. <br />
<br />
Create <b>spring-context.xml</b> file in WEB-INF and put the following lines into it:<br />
<br />
<pre class="brush: xml"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<context:component-scan base-package="com.blogspot.vozis.springvelocity.data" />
</beans>
</pre>
<br />
You need to modify <b>base-package</b> parameter according to your package name.<br />
<br />
Next, we need to register ContextListener that starts Spring Context on application start. Add the following lines to web.xml:<br />
<br />
<pre class="brush: xml"> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</pre>
<br />
<br />
<span style="font-size: large;">Creating templates</span><br />
<br />
Create new folder <b>views</b> in WEB-INF. This folder will contain Velocity templates. Application has 2 pages: list and detail, both having the same layout.<br />
<br />
Let's create layout file <b>layout.vm</b> and put it into <b>WEB-INF/views</b>:<br />
<br />
<pre class="brush: xml"><html>
<head>
<title>Spring MVC and Velocity</title>
</head>
<body>
<h1>Spring MVC and Velocity</h1>
$screen_content
<hr />
Copyright &copy 2012 Sergej Sizov
</body>
</html>
</pre>
<br />
As you may see <b>$screen_content</b> variable contains the content of pages.<br />
<br />
Now let's create <b>list.vm</b> and <b>detail.vm</b> pages:<br />
<br />
<br />
<pre class="brush: xml"><h2>List of Feeds</h2>
<ul>
#foreach($feed in $feeds)
<li><a href="/feed/${feed.id}">${feed.title}</a></li>
#end
</ul>
</pre>
<br />
<br />
<pre class="brush: xml"><h2>Detail of Feed</h2>
<p>Id: ${feed.id}</p>
<p>Title: ${feed.title}</p>
</pre>
<br />
<br />
<span style="font-size: large;">Configuring Spring MVC to use Velocity templates</span><br />
<br />
Create a file <b>servlet-context.xml</b> in <b>WEB-INF</b> and put the following lines into it:<br />
<br />
<pre class="brush: xml"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<mvc:annotation-driven />
<bean id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/views/" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="layoutUrl" value="layout.vm"/>
<property name="suffix" value=".vm" />
</bean>
<context:component-scan base-package="com.blogspot.vozis.springvelocity.web" />
</beans>
</pre>
<br />
<br />
Then register Spring Servlet to intercept all HTTP request. You need to add the following lines into <b>web.xml</b>:<br />
<br />
<pre class="brush: xml"> <servlet>
<servlet-name>servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</pre>
<br />
<br />
<span style="font-size: large;">Programming the Controller</span><br />
<br />
Create a new java class WebController:<br />
<br />
<pre class="brush: java">package com.blogspot.vozis.springvelocity.web;
import com.blogspot.vozis.springvelocity.data.FeedService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Controller
*
* @author sergej.sizov
*/
@Controller
public class WebController {
private FeedService feedService;
@Autowired
public WebController(FeedService feedService) {
this.feedService = feedService;
}
@RequestMapping("/")
public String list(ModelMap model) {
model.put("feeds", feedService.getFeeds());
return "list";
}
@RequestMapping("/feed/{id}")
public String detail(@PathVariable(value = "id") Integer feedId, ModelMap model) {
model.put("feed", feedService.getFeedById(feedId));
return "detail";
}
}
</pre>
<br />
Spring Controller is annotated with @Controller. Spring MVC automatically scans for @Controllers and creates mapping to methods according to @RequestMapping URL pattern.<br />
<br />
ModelMap map contains data to be passed to Velocity, the return parameter defines the template to be used (e.g. list, detail). <br />
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com5tag:blogger.com,1999:blog-1256788220020556950.post-46516229700165065962012-05-08T12:39:00.000-07:002015-01-03T06:02:13.477-08:00MySQL: Sort by column with NULLs on top<div dir="ltr" style="text-align: left;" trbidi="on">
Common task, when you need to sort table data by a column, that may have <b>null values</b> and you want to put nulls to the top.<br />
<br />
<a name='more'></a>Example table<br />
<br />
<pre>id | name | salary
---|------|-------
1 | John | 1000
2 | Mary | 500
3 | Paul | null
</pre>
<br />
The following SQL request sorts the table by salary putting the nulls on top:<br />
<br />
<pre>SELECT * FROM table ORDER BY IFNULL(salary, 0)
</pre>
<br />
Using <b>IFNULL(column, 0)</b> we simply substitute null with <b>zero</b>, so it gets to the top.<br />
<br />
Result:<br />
<br />
<pre>id | name | salary
---|------|-------
3 | Paul | null
2 | Mary | 500
1 | John | 1000
</pre>
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-60596832337370298402012-04-27T05:13:00.000-07:002012-04-27T05:13:00.237-07:00Java: Release resources on program termination<div dir="ltr" style="text-align: left;" trbidi="on">
Applications use different resources (database connections, file descriptors, etc.) that need to be released when program terminates. <br />
<br />
<a name='more'></a>Java application can register a ShutdownHook that would be executed before the last non-daemon process is terminated. It also works when application is terminated by <b>System.exit() </b>or external interrupt request (kill).<br />
<br />
Java <b>Runtime </b>has a method <b>addShutdownHook </b>that registers a <b>Thread </b>that would be started to do the cleaning up.<br />
<br />
Example, closing database connection on shutdown:<br />
<br />
<pre class="brush: java">// register shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
DatabaseFactory.shutdown();
}
});
</pre>
<br />
N.B.: ShutdownHook may not be executed if VM crashes.<br />
<br />
<br />
</div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-29074343362750632742012-03-18T10:35:00.000-07:002012-03-18T10:35:29.605-07:00Wicket TinyMCE and AjaxButton<div dir="ltr" style="text-align: left;" trbidi="on">
TinyMCE is a <b>WYSIWYG editor</b>, that can be used in Wicket to replace your TextAreas with a Rich Text Editor.<br />
<br />
<a name='more'></a>You need to add the following dependency into you pom.xml:<br />
<br />
<pre class="brush: xml"> <dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>wicketstuff-tinymce</artifactId>
<version>1.5.4</version>
</dependency>
</pre>
<br />
<br />
This would allow you to add <b>TinyMceBehaviour</b> to a TextArea that you want to transform into a WYSIWYG editor.<br />
<br />
<pre class="brush: java">TextArea contentTextArea = new TextArea("content");
// tinymce
contentTextArea.add(new TinyMceBehavior(new TinyMCESettings(Theme.advanced)));
contentTextArea.add(StringValidator.maximumLength(4000));
form.add(contentTextArea);
</pre>
<br />
<br />
Your <b><textarea></b> tag will be replaced by TinyMCE editor. On form submit, the content of TinyMCE editor is converted back into <textarea>.<br />
<br />
TinyMCE does not work with AjaxButtons, as AjaxButton does not call Form submit event. There is a work around for this. You need to call <b>triggerSave</b> on your AjaxButton onClick event:<br />
<br />
<pre class="brush: java">tinyMCE.triggerSave(true,true);
</pre>
<br />
To do this just add <b>TinyMceAjaxSubmitModifier</b> to your AjaxButton:<br />
<br />
<pre class="brush: java">ajaxButton.add(new TinyMceAjaxSubmitModifier());
</pre>
<br />
<br />
<br />
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com1tag:blogger.com,1999:blog-1256788220020556950.post-40277303673857464932012-03-13T11:29:00.003-07:002012-03-13T11:29:29.698-07:00Maven Jar Plugin: Setting Main-Class and Class-Path in Manifest<div dir="ltr" style="text-align: left;" trbidi="on">
To start a Java application you have to tell JVM where is the program's entry point (Main Class) and where to search for classes (Class Path). Main class must have a public static method called <b>main</b>, which takes command arguments and does the initialization. If your Java application is packaged into JAR you can define <b>Main-Class</b> and <b>Class-Path</b> in <b>manifest</b> file, so that JVM would be able to find your program's entry point and load necessary classes. To do so you can use <b>maven-jar-plugin</b> that generates manifest with Main-Class and Class-Path parameters.<br />
<br />
<a name='more'></a>Add the following lines into your <b>pom.xml</b>:<br />
<br />
<pre class="brush: xml"><plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>false</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
<mainClass>com.blogspot.vozis.MyApp</mainClass>
</manifest>
<manifestEntries>
<Class-Path>../conf/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</pre>
<br />
Definition of the parameters:<br />
<ul style="text-align: left;">
<li><b>addClasspath </b>- generates Class Path from your dependencies</li>
<li><b>mainClass </b>- name of the main class including package</li>
<li><b>manifestEntries </b>/ <b>Class-Path</b> - adds extra places to be added to Class Path</li>
</ul>
<br />
<span style="font-size: large;">Resulting manifest file:
</span><br />
<pre>Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: sergej.sizov
Build-Jdk: 1.5.0_22
Main-Class: com.blogspot.vozis.MyApp
Class-Path: ../conf/ xmlrpc-2.0.jar commons-httpclient-3.0.jar log4j-1.2.15.jar
</pre>
<br />
To start the application you no more need to define Main Class or Class Path using <b>-cp</b> parameter.<br />
<br />
Just run <span style="font-family: "Courier New",Courier,monospace;">java -jar MyApp.jar</span><br />
<br />
<br />
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-23538455230089215002012-03-13T04:50:00.000-07:002012-03-13T05:14:46.034-07:00Debugging PHP with Xdebug and Netbeans<div dir="ltr" style="text-align: left;" trbidi="on">
Many PHP programmers tend to develop their applications without special debugging tools. PHP developers are happy, because they do not have to wait for recompilation and redeploy, they just press F5 and see the results in browser. I call it <b>"echo" debug</b> method :). In this article I will show you how easy it is to install <b>Xdebug </b>debugger tool and use it in <b>Netbeans </b>IDE.<br />
<br />
<a name='more'></a>I use stand-alone installation of Apache 2.2, PHP 5.3 thread-safe. We need to download <b>Xdebug 2.1.4</b> that supports PHP 5.3 from <a href="http://xdebug.org/download.php">http://xdebug.org/download.php</a>. Linux users have to download Xdebug's source code and build it for concrete system. Windows users can download already compiled binaries.<br />
<br />
You have to choose the right version according to your version of PHP. To find out your version of PHP use <b>php -i</b> command or <b>phpinfo()</b>;<br />
<br />
<b>Xdebug 2.1.4</b> is available for :<br />
<ul style="text-align: left;">
<li>PHP 5.2 VC9 (32 bit),</li>
<li>PHP 5.2 VC9 TS (32 bit),</li>
<li>PHP 5.3 VC9 (64 bit),</li>
<li>PHP 5.3 VC9 (32 bit),</li>
<li>PHP 5.3 VC9 TS (64 bit),</li>
<li>PHP 5.3 VC9 TS (32 bit)</li>
</ul>
According to <b>phpinfo()</b> I use PHP version 5.3 thread-safe (TS), 32 bit x86, so I have to download PHP 5.3 VC9 TS (32 bit). <br />
<br />
<b>Warning</b>: do not use older version of Xdebug 2.1.3 as it crashes on <b>simplexml </b>object inspection.<br />
<br />
Then we put the downloaded library (extension) into PHP's extensions directory. In my case it is <b>d:\php5\ext</b> and I would rename it to <b>php_xdebug.dll</b> for short name.<br />
<br />
<br />
<span style="font-size: large;">Xdebug PHP extension configuration</span><br />
<br />
Open <b>php.ini</b> configuration file and add the following line:
<br />
<pre>zend_extension=d:\php5\ext\php_xdebug.dll</pre>
<br />
Then we need to allow remote debugging
<br />
<pre>xdebug.remote_enable=1</pre>
<br />
and configure<b> host, protocol and port</b> that would listen for debugger:
<br />
<pre>xdebug.remote_host=127.0.0.1
xdebug.remote_handler=dbgp
xdebug.remote_port=9000 </pre>
In some cases we need to see the debugger logs, e.g. when Xdebud crashes. You can turn on Xdebug logging with the following line:
<br />
<pre>xdebug.remote_log=d:\php5\xdebug.log</pre>
<br />
Save changes and restart Apache server.<br />
<br />
<br />
<span style="font-size: large;">Netbeans configuration</span><br />
<br />
In your Netbeans IDE open <b>Tools > Options > PHP</b>, select <b>Debugging </b>tab. Check that <b>Debugger port</b> is the the same as your <b>xdebug.remote_port</b> parameter (9000). <br />
<br />
If you want the debugger to stop at the first line of your application check "Stop at first line", otherwise debugger will stop at the first reached breakpoint.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxU1dkT0CYeoJbwLaLMQr4Sw9V1CtRngmG0eQkxC1fXLUhyphenhyphenoVq57tw1qAn1j629_kbTmaz-UiYzy2_ulb0IYdYqj2Hh2LehZ38nHxY3OYDfDK_hdbOR6viPf7ZthEUNM5IMXgQc6YmxZvy/s1600/nb1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="488" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxU1dkT0CYeoJbwLaLMQr4Sw9V1CtRngmG0eQkxC1fXLUhyphenhyphenoVq57tw1qAn1j629_kbTmaz-UiYzy2_ulb0IYdYqj2Hh2LehZ38nHxY3OYDfDK_hdbOR6viPf7ZthEUNM5IMXgQc6YmxZvy/s640/nb1.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Open your PHP project in Netbeans IDE, set a <b>breakpoint </b>by double-clicking on the row number or by pressing Ctrl + F8 and then start debugging by pressing Ctrl + F5.<br />
<br />
Use the following keyboard shortcuts to debug your code:<br />
<br />
<ul style="text-align: left;">
<li><b>Ctrl + F5</b> - Start debugging main project<b> </b></li>
<li><b>Ctrl + Shift + F5</b> - Start debugging main project</li>
<li><b>Shift + F5 / F5</b> - Stop / Continue</li>
<li><b>F4</b> - Run to cursor location</li>
<li><b>F7 / F8</b> - Step into / over</li>
<li><b>Ctrl + F7</b> - Step out</li>
<li><b>Ctrl + Alt + Up</b> - Go to called method</li>
<li><b>Ctrl + Alt + Down</b> - Go to calling method</li>
<li><b>Ctrl + F9</b> - Evaluate Expression</li>
<li><b>Ctrl + F8</b> - Toggle breakpoint</li>
</ul>
<br />
Lucky debugging!<br />
<br />
<br />
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com1tag:blogger.com,1999:blog-1256788220020556950.post-38721363614525711812012-02-29T07:05:00.000-08:002012-02-29T07:05:33.688-08:00Integer overflow in Java<div dir="ltr" style="text-align: left;" trbidi="on">
What would happen in Java when you <b>increment </b>an Integer variable that already contains its <b>maximum </b>value?<br />
<br />
<a name='more'></a>No, Java would not throw any exception :(<br />
<br />
Lets write a simple program to test it:<br />
<br />
<pre class="brush: java">
public static void main(String[] args) {
int i = Integer.MAX_VALUE;
System.out.println("Before: " + i
+ " = " + Integer.toBinaryString(i));
i++;
System.out.println("After: " + i
+ " = " + Integer.toBinaryString(i));
}
</pre>
<br />
The output is:<br />
<br />
<pre>Before: 2147483647 = 01111111111111111111111111111111
After: -2147483648 = 10000000000000000000000000000000
</pre>
<br />
As you see, it is <b>negative</b>.<br />
<br />
So, when you increment <b>Integer.MAX_VALUE</b> by 1 it becomes <b>Integer.MIN_VALUE</b>.<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-42526382818207259432012-02-21T12:41:00.000-08:002012-02-21T12:41:19.896-08:00Log4j filter to mask Payment Card numbers (PCI DSS)<div dir="ltr" style="text-align: left;" trbidi="on">
According to PCI DSS (Payment Card Industry Data Security Standard) your application <b>must not</b> store payment card numbers. This requirement includes database, files and logs. The following filter will allow you to mask card numbers in your logs <b>on the fly</b>, so even if you accidentally turned <b>debug mode</b> on for network communication, you can be confident that your data is PCI compliant.<br />
<br />
<a name='more'></a>Log4j allows you to configure <b>PatternLayout</b> that processes your log records. The idea is simple, out filter would match payment card numbers and replace them with masked values. Card number is usually a number of 15-19 digits.<br />
<br />
I am going to use <b>regular expression</b> to match possible card numbers and replace them with masked values. I leave unmasked the beginning (6 digits) and the ending (4 digits), replacing the middle part with <HIDDEN> text. So, instead of 123456789012345678, I will get 123456<HIDDEN>5678 in my logs.<br />
<br />
The following class implements <b>PatternLayout</b> with overriden <b>format()</b> method that does filtering:<br />
<br />
<pre class="brush: java">package vozis.logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
/**
* Credit Card Filtering Layout
* @author sergej.sizov
*/
public class CreditCardFilteringLayout extends PatternLayout {
private static final String MASKCARD = "$1<HIDDEN>$2";
private static final Pattern PATTERNCARD =
Pattern.compile("([0-9]{6})[0-9]{0,9}([0-9]{4})");
@Override
public String format(LoggingEvent event) {
if (event.getMessage() instanceof String) {
String message = event.getRenderedMessage();
Matcher matcher = PATTERNCARD.matcher(message);
if (matcher.find()) {
String maskedMessage = matcher.replaceAll(MASKCARD);
Throwable throwable =
event.getThrowableInformation() != null ?
event.getThrowableInformation().getThrowable() : null;
LoggingEvent maskedEvent = new LoggingEvent(
event.fqnOfCategoryClass,
Logger.getLogger(event.getLoggerName()),
event.timeStamp,
event.getLevel(),
maskedMessage,
throwable);
return super.format(maskedEvent);
}
}
return super.format(event);
}
}
</pre>
<br />
<br />
Then we need to configure Log4j to use CreditCardFilteringLayout. You need to override <b>layout</b> property for every <b>appender</b> in <b>log4j.properties</b> as it is shown below:<br />
<br />
<pre>log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
<b>log4j.appender.stdout.layout=vozis.logger.CreditCardFilteringLayout</b>
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss} %-5p %c{1} - %m%n
log4j.appender.stdout.Threshold=info
log4j.appender.TEMP=org.apache.log4j.RollingFileAppender
log4j.appender.TEMP.File=temp.log
log4j.appender.TEMP.MaxFileSize=5MB
log4j.appender.TEMP.MaxBackupIndex=1
<b>log4j.appender.TEMP.layout=vozis.logger.CreditCardFilteringLayout</b>
log4j.appender.TEMP.layout.ConversionPattern=%-5p %d{yyyy-MM-dd HH:mm:ss,SSS} %C{1}:%M(line %L) - %m%n
</pre>
<br />
This idea can be used not only for credit card numbers, but also for <b>Social Security number (SSN)</b> or any other data that you consider sensitive. The benefit of this solution is that it is a one place change and it is easier than checking every logger.log() invocation in your application.<br />
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com3tag:blogger.com,1999:blog-1256788220020556950.post-25716596215106923102012-02-20T05:38:00.001-08:002012-02-20T05:39:29.953-08:00Software Engineer - Weekends!<div dir="ltr" style="text-align: left;" trbidi="on">
What we do at weekends :)<br />
<br />
<a name='more'></a><br />
Click to enlarge<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAp0bL_XA9AvaGNFqeVZj2cDINsrne95LT876lsAif53ZkH0x6nWuJPa29SO55ahI1ja5Jq92tCQRyM2gRtou_I1TQvAeqnhObxWwmfHj6PthVGEcdZXPOZW63JP_Rgo9frnmNZJkonAu-/s1600/software-engineer.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAp0bL_XA9AvaGNFqeVZj2cDINsrne95LT876lsAif53ZkH0x6nWuJPa29SO55ahI1ja5Jq92tCQRyM2gRtou_I1TQvAeqnhObxWwmfHj6PthVGEcdZXPOZW63JP_Rgo9frnmNZJkonAu-/s400/software-engineer.jpg" width="400" /></a></div>
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-70691886236009102142012-02-19T14:58:00.001-08:002012-02-20T04:04:58.960-08:00Stop reinventing wheel, use Apache Commons<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Developer's life is full of routine tasks. We need to validate strings, convert data from different formats, compare objects and so on. Some developers tend to write everything on their own, reinventing common algorithms again and again. Every Java developer should look at <b>Apache Commons Lang</b> library as it already has everything we need every day.<br />
<br />
<a name='more'></a>When we work with Strings, we usually need to validate them (check if they are not null, not empty or do not contain some specific characters), transform, split, etc. <br />
<br />
<br />
These tasks can be easily done with the following classes: <b>StringUtils</b>, StringEscapeUtils, RandomStringUtils, Tokenizer, WordUtils. <br />
<br />
How often do you check this:<br />
<br />
<pre class="brush: java">if (str != null && str.trim().length() > 0) {
}
</pre>
<br />
<br />
when it can be easily done by:<br />
<br />
<pre class="brush: java">if (StringUtils.isNotBlank(str)) {
}
</pre>
<br />
<br />
List of methods available from <b>StringUtils</b>:<br />
<br />
<ul style="text-align: left;">
<li><b>IsEmpty/IsBlank</b> - checks if a String contains text</li>
<li><b>Trim</b>/<b>Strip </b>- removes leading and trailing whitespace</li>
<li><b>Equals </b>- compares two strings null-safe</li>
<li><b>IndexOf</b>/<b>LastIndexOf</b>/<b>Contains </b>- null-safe index-of checks</li>
<li><b>IndexOfAny</b>/<b>LastIndexOfAny</b>/<b>IndexOfAnyBut</b>/<b>LastIndexOfAnyBut </b>- index-of any of a set of Strings</li>
<li><b>ContainsOnly</b>/<b>ContainsNone </b>- does String contains only/none of these characters</li>
<li><b>Substring</b>/<b>Left</b>/<b>Right</b>/<b>Mid </b>- null-safe substring extractions</li>
<li><b>SubstringBefore</b>/<b>SubstringAfter</b>/<b>SubstringBetween </b>- substring extraction relative to other strings</li>
<li><b>Split</b>/<b>Join </b>- splits a String into an array of substrings and vice versa</li>
<li><b>Remove</b>/<b>Delete </b>- removes part of a String</li>
<li><b>Replace</b>/<b>Overlay </b>- Searches a String and replaces one String with another</li>
<li><b>Chomp</b>/<b>Chop </b>- removes the last part of a String</li>
<li><b>LeftPad</b>/<b>RightPad</b>/<b>Center</b>/<b>Repeat </b>- pads a String</li>
<li><b>UpperCase</b>/<b>LowerCase</b>/<b>SwapCase</b>/<b>Capitalize</b>/<b>Uncapitalize </b>- changes the case of a String</li>
<li><b>CountMatches </b>- counts the number of occurrences of one String in another</li>
<li><b>IsAlpha</b>/<b>IsNumeric</b>/<b>IsWhitespace</b>/<b>IsAsciiPrintable </b>- checks the characters in a String</li>
<li><b>DefaultString </b>- protects against a null input String</li>
<li><b>Reverse</b>/<b>ReverseDelimited </b>- reverses a String</li>
<li><b>Abbreviate </b>- abbreviates a string using ellipsis</li>
<li><b>Difference </b>- compares two Strings and reports on their differences</li>
<li><b>LevensteinDistance </b>- the number of changes needed to change one String into another </li>
</ul>
<br />
<br />
Now let's look at arrays. We check that arrays are not empty, we search for an element in array, we add/remove elements.<br />
<br />
<br />
<b>ArrayUtils</b> class helps with arrays. My favourite method is <b>ArrayUtils.contains()</b> that checks if an element is in array.<br />
<br />
<pre class="brush: java">if (ArrayUtils.contains(array, element)) {
}
</pre>
<br />
<br />
ArrayUtils contains commons operations for arrays of every primitive type and arrays of Objects:<br />
<br />
Object[] <b>add</b>(Object[] array, int index, Object element)<br />
Inserts the specified element at the specified position in the array.<br />
<br />
Object[] <b>add</b>(Object[] array, Object element)<br />
Copies the given array and adds the given element at the end of the new array.<br />
<br />
Object[] <b>addAll</b>(Object[] array1, Object[] array2)<br />
Adds all the elements of the given arrays into a new array.<br />
<br />
Object[] <b>clone</b>(Object[] array)<br />
Shallow clones an array returning a typecast result and handling null.<br />
<br />
boolean <b>contains</b>(Object[] array, Object objectToFind)<br />
Checks if the object is in the given array.<br />
<br />
int <b>getLength</b>(Object array)<br />
Returns the length of the specified array.<br />
<br />
int <b>hashCode</b>(Object array)<br />
Get a hashCode for an array handling multi-dimensional arrays correctly.<br />
<br />
int <b>indexOf</b>(Object[] array, Object objectToFind)<br />
Finds the index of the given object in the array.<br />
<br />
int <b>indexOf</b>(Object[] array, Object objectToFind, int startIndex)<br />
Finds the index of the given object in the array starting at the given index.<br />
<br />
boolean <b>isEmpty</b>(Object[] array)<br />
Checks if an array of Objects is empty or null.<br />
<br />
boolean <b>isEquals</b>(Object array1, Object array2)<br />
Compares two arrays, using equals(), handling multi-dimensional arrays correctly.<br />
<br />
boolean <b>isSameLength</b>(Object[] array1, Object[] array2)<br />
Checks whether two arrays are the same length, treating null arrays as length 0.<br />
<br />
boolean <b>isSameType</b>(Object array1, Object array2)<br />
Checks whether two arrays are the same type taking into account multi-dimensional arrays.<br />
<br />
int <b>lastIndexOf</b>(Object[] array, Object objectToFind)<br />
Finds the last index of the given object within the array.<br />
<br />
int <b>lastIndexOf</b>(Object[] array, Object objectToFind, int startIndex)<br />
Finds the last index of the given object in the array starting at the given index.<br />
<br />
Object[] <b>remove</b>(Object[] array, int index)<br />
Removes the element at the specified position from the specified array.<br />
<br />
Object[] <b>removeElement</b>(Object[] array, Object element)<br />
Removes the first occurrence of the specified element from the specified array.<br />
<br />
void <b>reverse</b>(Object[] array)<br />
Reverses the order of the given array.<br />
<br />
Object[] <b>subarray</b>(Object[] array, int startIndexInclusive, int endIndexExclusive)<br />
Produces a new array containing the elements between the start and end indices.<br />
<br />
Map <b>toMap</b>(Object[] array)<br />
Converts the given array into a Map.<br />
<br />
Integer[] <b>toObject</b>(int[] array)<br />
Converts an array of primitive ints to objects.<br />
<br />
int[] <b>toPrimitive</b>(Integer[] array)<br />
Converts an array of object Integers to primitives.<br />
<br />
int[] <b>toPrimitive</b>(Integer[] array, int valueForNull)<br />
Converts an array of object Integer to primitives handling null.<br />
<br />
String <b>toString</b>(Object array)<br />
Outputs an array as a String, treating null as an empty array.<br />
<br />
String <b>toString</b>(Object array, String stringIfNull)<br />
Outputs an array as a String handling nulls.<br />
<br />
<br />
Bonus :) The following classes help with building <b>toString</b>(), <b>hashCode</b>() and <b>equals</b>() methods: </div>
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<ul style="text-align: left;">
<li>EqualsBuilder</li>
<li>HashCodeBuilder</li>
<li>ToStringBuilder</li>
</ul>
<br />
For more detailed info see: <a href="http://commons.apache.org/lang/userguide.html">http://commons.apache.org/lang/userguide.html</a><br />
<br />
<br /></div>
</div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-19227020651695917622012-02-08T04:03:00.000-08:002012-02-08T04:03:09.409-08:00NetBeans: syntax highlighting for html templates with unsupported file extension<div dir="ltr" style="text-align: left;" trbidi="on">
<b>NetBeans </b>editor supports syntax highlighting and validation for several languages as Java, PHP, JavaScript, HTML. But if your file has different extension e.g. .template, NetBeans is unable to recognise the language. What you have to do if you want to turn on highlighting for <b>Smarty </b>or <b>Velocity templates</b>? <br />
<br />
<a name='more'></a>In Netbeans, choose <b>Options </b>from <b>Tools </b>menu. Choose <b>Miscellaneous</b>, then <b>Files</b>. On this tab you have the list of all file extensions that are supported by NetBeans editor.<br />
<br />
Click <b>New... </b>button and enter new file extension e.g. "template". Then choose corresponding Associated File Type (MIME): <b>HTML Files (text/html)</b>.<br />
<br />
All .template files will be recognised as html with syntax highlighting and validation.</div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-88600633967627605392012-02-08T02:45:00.000-08:002012-02-15T06:39:38.717-08:00CloseUtils: closing resources silently<div dir="ltr" style="text-align: left;" trbidi="on">
When working with <b>resources in Java</b> it is important that they are closed after use. Usually it is done by calling <b>close()</b> method in finally block. The problem is that close() method can throw an Exception. The following class allows you to close resources silently, so you save some try-catch lines.<br />
<br />
<a name='more'></a>Resources, since Java 1.5, implement <b>java.io.Closeable</b> interface:<br />
<br />
<pre class="brush: java">
interface Closeable {
public void close() throws IOException;
}
</pre>
<br />
So you can make a method, that would close any Closeable resource.<br />
<br />
<pre class="brush: java">
public class CloseUtils {
private static final Logger logger = Logger.getLogger(CloseUtils.class);
public static void close(java.io.Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (java.io.IOException e) {
logger.error("Error closing resourse/stream ", e);
}
}
}
}
</pre>
<br />
So, instead of having finally block like this:<br />
<br />
<pre class="brush: java">
InputStream is = ...
try{
...
} finally {
if (is != null) {
try {
is.close()
} catch (IOException e) {
logger.error(e);
}
}
}
</pre>
<br />
you can use the following code<br />
<br />
<pre class="brush: java">
InputStream is = ...
try {
...
} finally {
CloseUtils.close(is);
}
</pre>
<br />
P.S. Java 7 comes with a new construction called "<b>try with resources</b>" that automatically closes the resources that were declared in try block. See: <a href="http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html" target="_blank">The try-with-resources Statement</a><br />
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0tag:blogger.com,1999:blog-1256788220020556950.post-75288243374924834352012-02-05T15:09:00.000-08:002012-02-16T03:53:54.458-08:00Integrating Wicket with Spring<div dir="ltr" style="text-align: left;" trbidi="on">
In this short example I will show you how to integrate <b>Wicket 1.5</b> with <b>Spring 3</b>. Wicket is a rich web framework that allows creating web applications using simple html and Java code. Wicket has its own IOC/DI engine, but Spring has become a de-facto standard for service layer.<br />
<br />
<a name='more'></a>Let's start with a new Maven project. First we need to setup dependencies to be loaded from repositories.<br />
<br />
<b>Wicket Framework:</b><br />
<br />
<ul style="text-align: left;">
<li>wicket-core</li>
<li>wicket-util</li>
<li>wicket-ioc</li>
<li>wicket-request</li>
</ul>
<pre class="brush: xml"> <dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-core</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-util</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-ioc</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-request</artifactId>
<version>${wicket.version}</version>
</dependency></pre>
<br />
<br />
<br />
<b>Spring Framework:</b><br />
<ul style="text-align: left;">
<li>spring-context</li>
<li>spring-web</li>
</ul>
<pre class="brush: xml"><dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency></pre>
<br />
<br />
<br />
<b>Wicket-Spring Integration and Annotation Support:</b><br />
<br />
<pre class="brush: xml"><dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring</artifactId>
<version>${wicket.version}</version>
<!-- exclude spring framework that wicket pulls in -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring-annot</artifactId>
<version>${wicket-spring-annot.version}</version>
<!-- exclude spring framework that wicket pulls in -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency></pre>
<br />
<br />
<br />
Add these version constants to your POM properties:<br />
<br />
<pre class="brush: xml"><properties>
<spring.version>3.0.6.RELEASE</spring.version>
<wicket.version>1.5.4</wicket.version>
<wicket-spring-annot.version>1.3.7</wicket-spring-annot.version>
</properties></pre>
<br />
<br />
<br />
Then we need to register a listener that would load Spring context and a Wicket filter to process requests. Add the following lines to <b>web.xml</b>:<br />
<br />
<pre class="brush: xml"><context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:context.xml</param-value>
</context-param>
<servlet>
<servlet-name>wicket</servlet-name>
<servlet-class>org.apache.wicket.protocol.http.WicketServlet</servlet-class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value>
</init-param>
<init-param>
<param-name>applicationBean</param-name>
<param-value>wicketApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>wicket</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</pre>
<br />
<br />
Then we need to configure Spring Context, to turn on the annotation-driven configuration. Create a new file <b>context.xml</b> in your default package and put the following lines into it:<br />
<br />
<pre class="brush: xml"><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="web"/>
</beans></pre>
<br />
Then create a Java Class called <b>WicketApplication</b> in <b>web</b> package. This class will be our main Wicket Application class.<br />
<br />
<pre class="brush: java">package web;
import org.apache.wicket.Page;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.springframework.stereotype.Component;
/**
* Wicket Application
*
* @author sergej.sizov
*/
@Component("wicketApplication")
public class WicketApplication extends WebApplication {
@Override
public Class<? extends Page> getHomePage() {
return HomePage.class;
}
@Override
protected void init() {
// !!! - do not forget to call init on parent
super.init();
// initialize Spring
getComponentInstantiationListeners().add(new SpringComponentInjector(this));
}
}
</pre>
<br />
<br />
Now lets create a Spring Service that would return a message to be shown on our page.<br />
<br />
<pre class="brush: java">package web;
import org.springframework.stereotype.Component;
/**
* Hello Service
*
* @author sergej.sizov
*/
@Component("helloService")
public class HelloService {
public String getMessage() {
return "Hello World!";
}
}</pre>
<br />
<br />
Then we need to create a Home Page that will be shown as a default page. We need to create a HTML template and a Java class that would process actions and data binding.<br />
<br />
<b>web/HomePage.html</b><br />
<br />
<pre class="brush: xml"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:wicket="http://wicket.apache.org">
<wicket:head>
<title>Home Page</title>
</wicket:head>
<body>
<span wicket:id="msg" />
</body>
</html></pre>
<br />
<br />
<b>web/HomePage.java</b><br />
<br />
<pre class="brush: java">package web;<br /><br />import org.apache.wicket.markup.html.WebPage;<br />import org.apache.wicket.markup.html.basic.Label;<br />import org.apache.wicket.request.mapper.parameter.PageParameters;<br />import org.apache.wicket.spring.injection.annot.SpringBean;<br /><br /><br />/**<br /> * Home Page<br /> *<br /> * @author sergej.sizov<br /> */<br />public class HomePage extends WebPage {<br /><br /> @SpringBean<br /> protected HelloService helloService; <br /> <br /> public HomePage(final PageParameters parameters) {<br /> add(new Label("msg", helloService.getMessage());<br /> }<br /><br />}<br /></pre><br />
<br />
HelloService will be injected into Wicket Page using <b>@SpringBean</b> annotation.<br />
<br />
Integration is done. To see if it works we need to run it in a web container e.g. tomcat or jetty.<br />
<br />
If you want to test your Wicket application with <b>Jetty</b>, you can add the following lines into your build plugins:<br />
<br />
<pre class="brush: xml"><plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.16</version>
<configuration>
<contextPath>/</contextPath>
<scanTargets>
<scanTarget>target/classes/</scanTarget>
</scanTargets>
<scanIntervalSeconds>5</scanIntervalSeconds>
</configuration>
</plugin>
</pre>
<br />
<br />
Then just run Maven with <i>jetty:run</i> parameter:<br />
<br />
<b style="font-family: "Courier New",Courier,monospace;">mvn jetty:run</b><br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com2tag:blogger.com,1999:blog-1256788220020556950.post-22474894002821969092012-01-31T04:42:00.000-08:002012-01-31T04:45:38.073-08:00My Wicket improvement for StringValue was supported!<div dir="ltr" style="text-align: left;" trbidi="on">
Working with Wicket I was sadly surprised by the behaviour of <b>StringValue</b> class. I needed to get <b>optional parameters</b> from URL, such as page number or document id. This parameters may have values, but can be omited and should be replaced by <b>default value</b>.<br />
<br />
So I used this code
to get page number, default page is 1.<br />
<br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;">PageParameters parameters = ...
<br />
int currentPage = parameters.get("page").toInt(1); // default value is 1</span><br />
<br />
Unfortunatelly, <b>toInt(1)</b> throwed <b>StringValueConversionException</b> instead of returning 1.<br />
<br />
<br />
<a name='more'></a><br />
I submitted this improvement to Wicket Jira. <a href="https://issues.apache.org/jira/browse/WICKET-4356">WICKET-4356 : StringValueConversionException thrown when calling toInt(final int defaultValue) on StringValue. Why not to return the default value?</a><br />
<br />
<br />
<br />
Another Wicket user Robert McGuinness experienced the same:<br />
<br />
<blockquote class="tr_bq">
i ran into this issue as well, kinda wish the api would fail silently upon conversion and return defaults. Ex:<br />
http://wicket-stateless.herokuapp.com/?counter=8 (works)<br />
but I forgot to check for non ints so the following will fail (will be fixed soon)<br />
http://wicket-stateless.herokuapp.com/?counter=fails</blockquote>
<br />
This issue was also discussed in <span class="info"><a href="http://markmail.org/thread/4brd7ywrxt3vcyo2"><b>org.apache.wicket.dev</b></a> discussion group. </span><br />
<br />
<span class="info">Martin Grigorov:</span> <br />
<br />
Hi devs,<br />
<br />
<blockquote class="tr_bq">
At https://issues.apache.org/jira/browse/WICKET-4356 the reporter asks a reasonable question: why toXyz(default) throws a FormatException instead of returning the default value ? I agree with him. Is there a reason for the current behavior - the default value is used only if the text is null or empty but if non-empty and with the wrong format then the methods throw exception instead of logging it (DEBUG) and returning the default value.<br />
<br />
If you also agree then the next question is: should we change this behavior in 1.5.x or just in 6.0? </blockquote>
<br />
Sven Meier:<br />
<br />
<blockquote class="tr_bq">
I don't know the reason for this. Let's change it for 1.5.x too.</blockquote>
<br />
Igor Vaynberg:<br />
<br />
<blockquote class="tr_bq">
+1</blockquote>
<br />
Peter Ertl:<br />
<br />
<blockquote class="tr_bq">
+1 avoiding try..catch() for the simplest of use cases makes sense for me</blockquote>
<br />
And finally, the issue was solved by <span class="info">Martin Grigorov</span>:<br />
<br />
<blockquote class="tr_bq">
The behavior of all methods "toXyz(default)" has been changed as requested. </blockquote>
<br />
<br />
P.S. I am really happy to know that my idea was supported by the developers/maintainers of Wicket, because this small change would save many lines of try-catch, make code more secure and conversions would behave in a natural way. <br />
<br />
<br /></div>Sergejhttp://www.blogger.com/profile/15188174520807951751noreply@blogger.com0