저번달에 선테크데이를 다녀왔을 때 거기서 강조한 넷빈즈가 드디어 6.5버전을 릴리즈했네요.
우선 상세히 살펴보지는 않았는데요. 릴리즈 정보를 보면 엄청나게 막강해졌네요.

http://www.netbeans.org/community/releases/65/
여기에 가시면 주요특징을 나열해놨습니다.

PHP
어떤 분은 PHP가 너무 막강해져서 코딩하기 편해졌다고 하더라구요. 전 PHP를 안해봐서 패스 ㅠ

JavaScript and Ajax
또 어떤 분이 JavaScript코딩과 디버깅이 강력해졌다고 하더군요. 이건 정말 좋군요. 예전에 선테크데이에서 CSS와 JavaScript코드하이라이팅 등의 기능을 보여줬는데, 너무 잘 되더라구요^^ 그 외에 유명한 JS Framework를 지원하네요^^

Java EE & Web Development
향상된 Spring, Hibernate, JSF, JPA 등을 지원한다는군요. 이번버전에서 Hibernate에 신경을 많이 썼더고 쓰리다가 그랬던 것 같은데요. Hibernate가 대세이긴 한가봅니다^^ 저도 공부해봐야겠습니다 ㅠ

JavaFX
이건 아직 Preview SDK인데요. 선테크데이에서 드래그앤드랍코딩으로 손쉽게 애플리케이션을 만들었습니다. 앞으로 JavaFX 기대해도 좋을 듯 싶습니다. 공식지원하나봅니다. 아직 SDK가 Beta도 아닌데.....-_-;

GlassFish v3 Prelude for Web Development
이거 선테크데이에서 OSGi랑 설명을 하던데...잘 모르므로 패스-_-;

C/C++
저기 특징중에 좀 맘에 드는 것이 Remote development라는 것이 있는데요. 저것이 된다면 엄청 편하겠는데요? 한번 해봐야겠습니다. C쪽은 보통 서버에서 컴파일되서 돌아가는 프로그램이 많아서-_-; 원격 개발이 되야합니다 ㅠ

그 외 Debugger도 향상되고, 이것저것 많이 향상되었네요.
전 맘에 드는 기능은 JavaFX랑 Hibernate랑 Javascript! 자....공부하러 고고싱~

 
Posted by 머드초보
,
 
ActionScript3가 제공하는 Sound클래스에서 구하는 재생시간은 구하는데 너무 오래걸립니다.
Sound객체를 생성에 Complete이벤트가 발생한 다음에야 재생시간을 구할 수 있습니다.
재생목록에 추가를 해서 그냥 간단히 재생시간을 보여줘야하는데, 100곡을 재생목록에 추가를 해버리면 AIR애플리케이션이 미친듯이 메모리를 잡아먹는 것을 볼 수 있습니다-_-;

그래서 찾아보니, mp3 Header정보를 이용해서 재생시간을 구할 수 있습니다.

재생시간 = 파일크기 * 8 / 비트레이트 로 구할 수 있습니다.
그러면 비트레이트만 구하면 되는데, 이건 MP3Header에서 찾을 수 있습니다.

MP3 BITRATE는 http://www.datavoyage.com/mpgscript/mpeghdr.htm에 의하면 MPEG버전, LAYER, Bitrate Index로 구할 수 있습니다. MP3는 각각 Frame별로 Header가 존재하는데, 거기서 위에 정보를 구할 수 있는 것 같습니다.

ID3v2태그가 있는 경우는 ID3v2태그 다음에 MP3Header가 나옵니다. 그렇다면 ID3v2태그의 길이를 구해서 그 다음부터 MP3Header를 찾아야 합니다. ID3v2태그는 길이가 가변적입니다.그래서 총길이를 알아야하는데, 총길이는 ID3v2태그 맨 앞에 나오는 10byte Header부분에서 구할 수 있습니다.

이 Header부분의 6byte~10byte까지가 ID3v2의 총 길이인데요. 여기의 값이 00 00 1F 76(00011111 01110110)이라면 각각 MSB를 제거하여 붙인 값이 총 길이가 된다더군요. 00111111110110 -> 4086byte.

우선 C#으로 구현해놓은 소스가 있습니다. 그것을 Actionscript3로 변환했습니다(구현하려니 힘들어서 ㅠ)
C#소스 -> http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=79

제가 변환한 AS3용 MP3Header클래스입니다. 제가 가지고 있는 MP3 대부분 테스트해봤는데 잘 되더라구요.
invalid-file

MP3Header클래스


사용법은 이렇게 쓰시면 됩니다.
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="init()">
    <mx:Script>
        <![CDATA[
            import util.MP3Header;
            private function init():void
            {
                var mp3Header:MP3Header = new MP3Header();
                mp3Header.readMP3Information("D:/눈물이 글썽 - 서진영.MP3");
                trace("BITRATE = " + mp3Header.intBitRate);
                trace("Frequency = " + mp3Header.intFrequency);
                trace("Mode = " + mp3Header.strMode);
                trace("LengthFormatted = " + mp3Header.strLengthFormatted);
                trace("Length = " + mp3Header.intLength);
            }
        ]]>
    </mx:Script>   
</mx:WindowedApplication>
[/code]
[code]
BITRATE = 64
Frequency = 44100
Mode = Stereo
LengthFormatted = 04:00
Length = 240
[/code]

 
Posted by 머드초보
,
 
셋팅이 완료되었으니 이제 controller를 만들어봅시다.
src폴더에 openidtest.controller라는 package를 만듭시다.
그리고, OpenIDController클래스를 생성합니다.
OpendIDController.java
[code]
package openidtest.controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.openid4java.OpenIDException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthRequest;
import org.openid4java.message.ParameterList;
import org.openid4java.server.RealmVerifier;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

public class OpenIDController
{
private ConsumerManager manager;
   
    @RequestMapping(value="/index.do", method=RequestMethod.GET)
    public String indexGetcontroller(ModelMap model)
    {
        return "index";
    }
   
    @SuppressWarnings("unchecked")
    @RequestMapping(value="/index.do", method=RequestMethod.POST)
    public String indexPostController(String openId, ModelMap model,
            HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException
    {
        try
        {
            manager = new ConsumerManager();
           
            String returnToUrl = "http://localhost:8080/OpenIdTest/verify.do";
           
            List discoveries = manager.discover(openId);
            if (discoveries.size() == 0)
            {
                model.addAttribute("noopenid", openId);
                return "index";
            }
            DiscoveryInformation discovered = manager.associate(discoveries);
            request.getSession().setAttribute("openid-disc", discovered);
            RealmVerifier rv = new RealmVerifier();
            rv.setEnforceRpId(false);
            manager.setRealmVerifier(rv);
            AuthRequest authReq = manager.authenticate(discovered, returnToUrl);
           
            if (!discovered.isVersion2())
            {
                // Option 1: GET HTTP-redirect to the OpenID Provider endpoint
                // The only method supported in OpenID 1.x
                // redirect-URL usually limited ~2048 bytes
                response.sendRedirect(authReq.getDestinationUrl(true));
                return null;
            } else {
                // Option 2: HTML FORM Redirection (Allows payloads >2048 bytes)

                // RequestDispatcher dispatcher =
                // getServletContext().getRequestDispatcher("formredirection.jsp");
                // httpReq.setAttribute("prameterMap",
                // response.getParameterMap());
                // httpReq.setAttribute("destinationUrl",
                // response.getDestinationUrl(false));
                // dispatcher.forward(request, response);
            }
           
        }
        catch (OpenIDException e)
        {
        }
        return null;
        //model.addAttribute("openId", openId);
        //return "index";
    }
   
    @RequestMapping(value="/verify.do", method=RequestMethod.GET)
    public String verifyController(String openId, ModelMap model,
            HttpServletRequest request,
            HttpServletResponse response) throws ServletException
    {
        try
        {
            ParameterList paramList = new ParameterList(request.getParameterMap());
            DiscoveryInformation discovered = (DiscoveryInformation) request
            .getSession().getAttribute("openid-disc");
           
            // extract the receiving URL from the HTTP request
            StringBuffer receivingURL = request.getRequestURL();
            String queryString = request.getQueryString();
            if (queryString != null && queryString.length() > 0)
                receivingURL.append("?").append(request.getQueryString());
           
            // verify the response; ConsumerManager needs to be the same
            // (static) instance used to place the authentication request
            VerificationResult verification = manager.verify(receivingURL.toString(),
                    paramList, discovered);
           
            // examine the verification result and extract the verified
            // identifier
            Identifier verified = verification.getVerifiedId();
            if (verified != null)
            {
                request.getSession()
                    .setAttribute("openid", verified.getIdentifier());
            }
        }
        catch (OpenIDException e)
        {
        }
       
        return "redirect:index.do";
    }
   
    @RequestMapping(value="/logout.do", method=RequestMethod.POST)
    public String logoutController(String openId, ModelMap model,
            HttpServletRequest request,
            HttpServletResponse response) throws ServletException
    {
        request.getSession().removeAttribute("openid");
        return "redirect:index.do";
    }
}
[/code]
WEB-IINF/jsp/index.jsp
[code]
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>오픈아이디 테스트</title>
</head>
<body>
<c:choose>
    <c:when test="${sessionScope.openid != null}">
        ${sessionScope.openid}님 환영합니다.
        <form action="logout.do" method="POST">
            <input type="submit" value="로그아웃"/>
        </form>
    </c:when>
    <c:otherwise>
        <form action="index.do" method="POST">
            <input type="text" id="openId" name="openId"/>
            <input type="submit" value="로그인"/>
        </form>
    </c:otherwise>
</c:choose>
<c:if test="${noopenid != null}">
    ${noopenid}는 없는 아이디입니다.
</c:if>
</body>
</html>
[/code]
view페이지에서 아이디를 치고, post요청을 하게 되면 indexPostController메소드가 호출이 됩니다. 여기서는 인증할 수 있는 URL을 redirect하게 됩니다. 그러면 OpenID를 제공하는 Provider에서 인증을 받고, returnURL로 이동을 해서 인증이 되었는지 확인 후 인증이 되면
Identifier verified = verification.getVerifiedId();
에서 Identifier 객체를 받을 수 있는데요. 이곳에서 오픈아이디를 구할 수 있습니다.

아 졸려-_-

 
Posted by 머드초보
,
 
우선 rath님이 올리신 글과 outsider님이 올리신 글을 참조했습니다.
(거의 똑같네-_-)

근데 이상하게 톰캣로그에서는 에러가 막 떨어지는데, 되네요-_-; 좀 더 확인해봐야겠네요 ㅠ

xrath님의 J2EE 환경에서 OpenID 지원 사이트 구축해보기
outsider님의 http://blog.outsider.ne.kr/164 http://blog.outsider.ne.kr/166

테스트환경은 TOMCAT6.0.18 + JDK 6u10 + Spring 2.5.6 입니다.

우선 http://code.sxip.com/ 이곳에서 라이브러리를 받습니다.
이클립스를 열어서 프로젝트를 하나 만듭시다.

Dynamic Web Project로 해서 만듭시다.
OpenIdTest라는 프로젝트로 만듭시다.

WEB-INF/lib에 라이브러리를 복사해야합니다. java-openid-sxip-0.9.4.jar이거 하나만 있으면 되는 줄 알았는데, lib폴더에 있는거 거의 다 필요하더군요-_-;
java-openid-sxip-0.9.4.jar
lib/commons-codec-1.3.jar
lib/commons-httpclient-3.0.1.jar
lib/commons-logging-1.03.jar
lib/htmlparser.jar
lib/openxri-client.jar
lib/openxri-syntax.jar
lib/endorsed/dom3-xercesImpl.jar
lib/endorsed/dom3-xml-apis.jar
lib/endorsed/xalan-2.6.0.jar
lib/xri/xmlsec-1.1.jar

그 외, 스프링과 jstl을 사용하기 위한 라이브러리를 복사합니다.
spring.jar
spring-webmvc.jar
standard.jar
jstl.jar

스프링을 위한 셋팅을 해봅시다.
web.xml파일을 수정합니다.
[code]
<?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_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>OpenIdTest</display-name>

    <!-- SPRING FRAMEWORK DISPATCHER SERVLET CONFIGURATIONS -->
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class> org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>redirect.jsp</welcome-file>
    </welcome-file-list>
</web-app>
[/code]
WebContent밑에 redirect.jsp파일을 생성합니다.
redirect.jsp
[code]
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>OPENID TEST</title>
</head>
<body>
<% response.sendRedirect("index.do"); %>
</body>
</html>
[/code]
WEB-INF 밑에 spring-servlet.xml을 생성합니다.
spring-servlet.xml
[code]
<?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.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- ANNOTATION CONTEXT DEFINITION -->
    <context:annotation-config />
    <context:component-scan base-package="openidtest" />
   
    <!-- VIEW RESOLVER CONFIGURATIONS -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
   
</beans>
[/code]
아... 이제 셋팅이 완료되었어요.
다음 글에 계속.....-_-;

 
Posted by 머드초보
,
 
다...다른 방법을 검색해서 구했습니다-_-;
하지만, 이건 한글은 이제 잘 읽는 것 같은데......한자를 못 읽습니다-_-; 원래 안되는건가....-_-;

우선 ID3Parser 링크입니다. 매우 빠른 속도로 ID3데이터를 가져옵니다.
http://blog.ashier.com/2007/11/08/id3-parser/

여기서 한글을 읽을 수 있게 수정하는 부분이......
보면 ID3데이터를 추출해오는 부분이 있습니다.
거기서 한글로 추출할 수 있게 변경합니다.

[code]
private function parseFrames():void {
    var id:String = "";
    var size:uint = 0;
    if(fs.position <length) {
        try {
            id = fs.readUTFBytes(frameIdSize);
            size = fs.readUnsignedInt();
            if (version>= 3) {
                fs.readByte();
                fs.readByte();
            }
            if(id.match(regEx)) {
                var obj:Object = new Object();
                obj.encoding = fs.readByte();
                obj.text = fs.readUTFBytes(size - 1);
                frames[id] = obj;
            }
            parseFrames();
        }catch(e:Error) {}
    }
}
[/code]
이 부분이 있는데요. 한글을 읽어오는 readUTFBytes 부분을 바꿔줍니다.
[code]
//obj.text = fs.readUTFBytes(size - 1);
if (obj.encoding == "1")
{
    obj.text = StringUtil.trim(fs.readMultiByte(size - 1, "unicode"));
}
else
{
    obj.text = StringUtil.trim(fs.readMultiByte(size - 1, "EUC-KR"));
}
[/code]
보니까 obj.encoding이 1인 값은 unicode로 인코딩 된 것 같아요. obj.encoding이 0인 값은 EUC-KR로...
이렇게 하니까 잘 되네요....가끔 공백을 추출해오고 그래서 trim처리했습니다.

아래글은 ID3v1방식 추출 방법 및 ID3v2의 다른 추출 방식 입니다^^ 참고하세요~
http://mudchobo.tomeii.com/tt/356
 
Posted by 머드초보
,