IS_NUMERIC, IS_NUMBER oder ähnliches…

Kann sein, dass es in einem großen Datenbankprodukt namens Oracle keine Methode isNumeric oder ähnliches gibt, die mir sagt, ob ein String eine Zahl repräsentiert? Es kann…

Deswegen hier eine kleine Methode:

CREATE OR REPLACE FUNCTION f_makeNumber(inval IN VARCHAR2) RETURN NUMBER IS
  rv NUMBER;
  numCharSet VARCHAR2(32);
BEGIN
  SELECT VALUE
  INTO   numCharSet
  FROM   nls_session_parameters
  WHERE  parameter = 'NLS_NUMERIC_CHARACTERS';
 
  BEGIN
    SELECT DECODE(
             NVL(LENGTH(TRANSLATE(TRIM(inval),' +-.,0123456789',' ')),0),
              0,TO_NUMBER(
                CASE WHEN VALUE = '.,' THEN
                  REPLACE(inval, ',','.')
                     WHEN VALUE = ',.' THEN
                  REPLACE(inval, '.',',')
                END              
              ),
              NULL
           )
    INTO   rv
    FROM   nls_session_parameters
    WHERE  parameter = 'NLS_NUMERIC_CHARACTERS';
  EXCEPTION WHEN invalid_number THEN
    rv := NULL;
  END;
 
  RETURN rv;
 
END f_makeNumber;
/

Diese Methode gibt den Zahlenwert des Strings ‘inval’ zurück, falls es sich um eine Zahl handelt, ansonsten null. NLS_NUMERIC Characters werden berücksichtigt (2.0 und 2,0 werden beides zu Zahlen), Strings wie 2.000,0 lassen sich damit allerdings nicht verarbeiten.

| Comments (1) »

18-Oct-06



Kaputte UTF-8 Daten im Servlet

Beruflich habe ich gerade mit einer Webanwendung zu tun, die mit Spring realisiert ist. Spring macht ähnlich viel Spaß wie Ruby und ist bis jetzt das erste J2EE Framework, dass mir von Anfang zusagte und es auch schaffte, mich zu begeistern.

Die Webanwendung ist komplett UTF-8 basiert. Soweit so gut. Leider mußte ich feststellen, dass Eingaben per form nicht so ankamen, wie ich mir das vorgestellt hatte, irgendwo ging das Characterset verloren.

Ich nutze zur Zeit Java 1.5.0.8, Apache Tomcat 5.5.17, Spring 1.2.8 sowie Hibernate 3.1.x. Irgendwo im Zusammenspiel der ersten drei Komponenten trat der Fehler auf, obwohl ich in allen beteiligten JSP Dateien den Content Type angegeben habe. Ich habe mir jetzt mit folgenden Filter beholfen, der dafür sorgt, dass UTF-8 auch als solches ankommt:

package filter;
 
import java.io.IOException;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
public class CharsetFilter implements Filter {
	FilterConfig config;
	String encoding = "UTF-8";
 
	/**
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {
	}
 
	/**
	 * Sets the character encoding on the request
	 * @see javax.servlet.Filter#doFilter(javax.servlet.Servle tRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		request.setCharacterEncoding(encoding);
		chain.doFilter(request, response);
	}
 
	/**
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConf ig)
	 */
	public void init(FilterConfig config) throws ServletException {
		this.config = config;
		this.encoding = config.getInitParameter("requestEncoding");
	}
}

Der Filter kann im web.xml einfach konfiguriert werden:

<filter>
	<filter-name>
		charsetFilter
	</filter-name>
	<filter-class>
		filter.CharsetFilter
	</filter-class>
	<init-param>
		<param-name>requestEncoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
</filter>
 
<filter-mapping>
	<filter-name>charsetFilter</filter-name>
	<url-pattern>/app/html/*</url-pattern>
</filter-mapping>

| Comments (0) »

05-Oct-06


FastCGI und Standard Out

Gestern habe ich mich eine kleine Ewigkeit mit Ruby on Rails, RMagick und FastCGI geärgert.

Mit kleinen Schwierigkeiten habe ich meine ImageMagick Installation soweit gebracht, dass RMagick und Rails problemlos funktionierten.

Ziel war ein Imageupload mit anschliessender Verarbeitung durch RMagick. Da nicht immer eine temporäre Datei beim Upload ensteht, habe ich mich an ein Tutorial gehalten, wo folgende Code empfohlen wurde:

Magick::Image::read_inline(Base64.b64encode(feld.read)).first

Image::read_inline liest einen Base64 kodierten String. Soweit kein Problem, es funktionierte auch alles. Bis ich wieder auf Production und somit auf FastCGI umschaltete.

Die Anwendung stürzte nach dem Upload und der Verarbeitung der Bilder ab.

Im Apache error.log stand nur:

 FastCGI: comm with server "/Users/msimons/Entwicklung/rails/daily/public/dispatch.fcgi" aborted: error parsing headers: malformed header '/9j/4TseRXhpZgAASUkqAAgAAAALAA4BAgAgAAAAkgAAAA8BAgAFAAAAsgAA'

Drollig. Ich hab längere Zeit gesucht, bis ich den Hinweis fande, dass man beim FastCGI Prozess besser nicht ins Stdout schreibt. Genau das macht Base64.b64encode aber. Hatte mich schon geärgert, weil das verlangsamt das ganze natürlich bei großen Dateien.

Wenn ich obige Zeile in

Magick::Image::read_inline(Base64.encode64(feld.read)).first

ändere, ist alles in bester Ordnung. Der Malformed Header hatte ergo nichts mit RMagick zu tun. Toll.

| Comments (0) »

03-Oct-06


Spring und JNDI Datasources

Ich nutze gerade das J2EE Framework Spring zusammen mit Hibernate und Oracle für eine Webanwendung.

Die Hibernate DataSource kann entweder über eine DriverManagerDataSource und Angabe der Verbindungsparameter innerhalb der Webanwendung gesteuert werden, oder es kann eine JNDI Datasource des Application Containers (in dem Fall Tomcat) genutzt werden:

<bean id="serverDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiName"  value="java:comp/env/jdbc/blah"/>
</bean>

Der Trick dabei ist, den vollständigen Namen der DataSource anzugeben, also “java:comp/env/jdbc/blah” statt “jdbc/blah”, ansonsten bekommt nur “javax.naming.NameNotFoundException: Name jdbc is not bound in this Context” um die Ohren geschlagen, auch wenn man die DataSource im Tomcat konfiguriert hat.

Bah, das sowas immer soviel Zeit kosten muss….

| Comments (0) »

21-Sep-06