모델 데이타를 XML 형식으로 출력할 수 있습니다.

1. 컨트롤러를 만들고 등록합니다.

public class ViewMemberListWithXMLController extends AbstractController{

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
        List<MemberInfo> infos = ServiceManager.getMemberInfoService().getAll();
        Map<String, Object> members = new HashMap<String, Object>();
        members.put("members", infos);
        return new ModelAndView("memberListXml", members);
    }

}

<bean name="/viewMemberListWithXml.html" class="net.ailgejava.members.controller.ViewMemberListWithXMLController" />

2. 모델 데이타를 XML 로 만드는 view 클레스를 만듭니다.

public class MemberListXMLView extends AbstractXsltView {

    @SuppressWarnings("unchecked")
    @Override
    protected Source createXsltSource(Map model, String rootName, HttpServletRequest request, HttpServletResponse response) throws Exception {
        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        Element root = document.createElement(rootName);

        List<MemberInfo> memberInfos = (List<MemberInfo>) model.get("members");
        for (MemberInfo memberInfo : memberInfos) {
            String name = memberInfo.getName();
            String email = memberInfo.getEmail();
            String home = memberInfo.getHome();
            String pictureAddress = memberInfo.getPictureAddress();

            Element memberInfoNode = document.createElement("memberInfo");
            Text nameText = document.createTextNode(name);
            Text emailText = document.createTextNode(email);
            Text homeText = document.createTextNode(home);
            Text pictureAddressText = document.createTextNode(pictureAddress);

            memberInfoNode.appendChild(nameText);
            memberInfoNode.appendChild(emailText);
            memberInfoNode.appendChild(homeText);
            memberInfoNode.appendChild(pictureAddressText);

            root.appendChild(memberInfoNode);
        }

        return new DOMSource(root);
    }
}

이때 Text, Element, Document 객체의 패키지는 org.w3c.dom 패키지 입니다. 레퍼런스의 예제는 Generic을 사용하지 않는 Map과 List 그리고 Iterator를 명시적으로 사용하고 있더군요. Java 5버전 형태로 바꿔주면 좋을텐데 말이죠. :)

변수와 메소드 이름의 작명을 잘해뒀기 때문에 직감적으로 대강 어떻게 코딩 해야 하는지 알 수 있습니다.

3. 뷰 프로퍼티 파일 정의하기.

memberListXml.class = net.ailgejava.members.view.xml.MemberListXMLView
memberListXml.stylesheetLocation=/WEB-INF/xsl/memberList.xslt
memberListXml.root=memberInfos

class 는 위에서 만든 view 클레스
stylesheetLocation은 XML을 HTML로 변환하여 보여줄 xslt 의 위치
root 는 XML의 root 엘리먼트 이름을 나타냅니다.

뷰 프로퍼티 파일을 썼다는 것은 ResourceBundleViewResolver를 사용하였다는 것입니다. 기존에 사용하던 리졸버와 상관없이 추가로 등록해 주면 됩니다. 대신 어차피 기본적으로 InternalResourceViewResolver 이 녀석이 Resolver Chaining 할 때 맨 뒤로 가긴 하지만 그래도 명시적으로 order 프로퍼티를 사용하여 순서를 명확히 해줍니다.

    <!-- View Resolver -->
    <!-- XML, Exel, PDF -->
    <bean id="ExViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
          <property name="basename" value="views"/>
          <property name="order" value="1" />
    </bean>

    <!-- jstl -->
    <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" />
        <property name="order" value="2" />
    </bean>


4. XSLT 만들기

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="html" omit-xml-declaration="yes"/>

    <xsl:template match="/">
        <html>
            <head><title>AJN Members</title></head>
            <body>
                <h1>전체 회원 목록(XML)</h1>
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="memberInfo">
        <xsl:value-of select="."/><br/>
    </xsl:template>

</xsl:stylesheet>

<xsl:apply-templates/> 이녀석은 xml 보여줄 곳을 명식하는 것 같고 이 부분에 뿌려줄 내용을 아랫 부분에서 정의해 주는 것 같습니다. 저기서 memberInfo 는 위의 View 클레스 만들 때 사용한 Element의 이름과 동일해야 합니다.

5. 데모

사용자 삽입 이미지 
사용자 삽입 이미지