Posts Tagged “slim3”


これでいいのかしら。。


    public static Key allocateId(AsyncDatastoreService ds, String kind)
            throws NullPointerException {
        if (ds == null) {
            throw new NullPointerException("The ds parameter must not be null.");
        }
        if (kind == null) {
            throw new NullPointerException(
                "The kind parameter must not be null.");
        }
        String ns = NamespaceManager.get();
        if (ns == null) {
        	ns = "";
        }
        String cacheKey = "!"+ns+":"+kind;
        Iterator<Key> keys = keysCache.get(cacheKey);
        if (keys != null && keys.hasNext()) {
            return keys.next();
        }
        keys =
            FutureUtil
                .getQuietly(allocateIdsAsync(ds, kind, KEY_CACHE_SIZE))
                .iterator();
        keysCache.put(cacheKey, keys);
        return keys.next();
    }

Comments [appengine][slim3] DatastoreUtil#allocateIdがNamespaceに対応するように修正 はコメントを受け付けていません。


listプロパティにInMemoryInCriterionを適用するとエラーになるので修正。
これでいいのかしら。。


   public boolean accept(Object model) {
        Object v = convertValueForDatastore(attributeMeta.getValue(model));
        for (Object o : value) {
        	if (v instanceof Collection<?>) {
        		for (Object v2: (Collection<?>)v) {
                    if (compareValue(v2, o) == 0) {
                        return true;
                    }
        		}
        	} else {
        		if (compareValue(v, o) == 0) {
        			return true;
        		}
        	}
        }
        return false;
    }

Comments [appengine][slim3]InMemoryInCriterionがlistプロパティでも動作するように修正 はコメントを受け付けていません。


概要

appengineでJSON-RPCサーバーのようなものを作りたいときなど ServletRequest#getInputStream()で取得できるInputStreamを使いたい場合があります。ところがslim3のcontrollerでこれをやろうとするとInputStreamのIllegalStateExceptionが発生します。
Jettyや大概のサーブレットサーバーは getInputStreamとgetParameter(s)を同時には使えないようです。
JSON-RPCならslim3のcontrollerは使う必要ないじゃんといえばそれまでなのですができれば慣れているもので全てやってしまいたいというのも事実。そこで以下のようなworkaroundで回避します。

  1. StreamFilterを作って、そこでServletRequestをWrapperクラスに置き換える (一番最初にこのFilterが動くようにする)
  2. RequestWrapperでは getInputStreamをoverrideし、Streamを再利用可能にする

なお、このworkaroundは ServletInputStreamを2回使う – うさ☆うさ日記 にて紹介されているやり方とほぼ同じです。(ナイスポストありがとうございました!)

StreamFilter


public class StreamFilter implements Filter {

    public void destroy() {
        // TODO Auto-generated method stub

    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        
        HttpServletRequest req = (HttpServletRequest)request;
        request = new BufferedServletRequestWrapper( req );
        chain.doFilter(request, response);
    }

    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

BufferedServletRequestWrapper


public class BufferedServletRequestWrapper extends HttpServletRequestWrapper {
    
    private byte[] buffer;

    public BufferedServletRequestWrapper(HttpServletRequest request) throws IOException {
        super( request );

        InputStream is = request.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte buff[] = new byte[ 1024 ];
        int read;
        while( ( read = is.read( buff ) ) > 0 ) {
            baos.write( buff, 0, read );
        }

        this.buffer = baos.toByteArray();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new BufferedServletInputStream( this.buffer );
    }

}

BufferedServletInputStream


public class BufferedServletInputStream extends ServletInputStream {

    private ByteArrayInputStream inputStream;

    public BufferedServletInputStream(byte[] buffer) {
        this.inputStream = new ByteArrayInputStream( buffer );
    }

    @Override
    public int available() throws IOException {
        return inputStream.available();
    }

    @Override
    public int read() throws IOException {
        return inputStream.read();
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        return inputStream.read( b, off, len );
    }

}

参考

Comments slim3のcontrollerでServletInputStreamを使いたいとき はコメントを受け付けていません。