Spring MVC – 22 – XML View & JAXB | @XmlRootElement | @ResponseBody

Merhaba Arkadaslar
Bu bolumde XML (Extensible Markup Language ) view ve JAXB kavramini inceleyecegiz.
JAXB ( Java Architecture for XML Binding ) yi kullanarak XML -> Java ve Java -> XML donusumlerini gerceklestirebiliriz.

  • Marshalling – Java objelerini -> XML e donusturme islemi
  • Unmarshalling – XML icerigini Java objelererine donusturme islemi

JAXB icin herhangi bir dependency/jar eklememiz gerekmemektedir. JDK bunyesinde JAXB annotationlari mevcuttur.

Way 1

JAXBPersonController.java
@ResponseBody annotation ‘ini kullanildiginda  uygun formata donusturme islemi yapilir. Uygun formatlar , JSON , XML vs.
Spring bunun icin uygun HttpMessageConverter implementation’ini kullanir. Marshalling icin Spring varsayilan olarak org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter sinifini kullanir.

package _23.jaxb.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import _23.jaxb.model.Person;
import _23.jaxb.model.PersonList;

@Controller
public class JAXBPersonController {

	@RequestMapping("/getPersonXML")
	@ResponseBody
	// http://localhost:8080/injavawetrust.springmvc/getPersonXML
	public Person getPersonXML() {
		return new Person("1", "Levent", "Erguder", "1989");
	}

	@RequestMapping("/getPersonListXML")
	@ResponseBody
	// http://localhost:8080/injavawetrust.springmvc/getPersonListXML
	public PersonList getPersonListXML() {
		// prepare data
		Person person1 = new Person("1", "Levent", "Erguder", "1989");
		Person person2 = new Person("2", "James", "Gosling", "1955");
		Person person3 = new Person("3", "Joshua", "Bloch", "1961");

		List<Person> persons = new ArrayList<Person>();
		persons.add(person1);
		persons.add(person2);
		persons.add(person3);

		PersonList personList = new PersonList(persons);

		return personList;
	}
}

Person.java
@XmlRootElement ve @XmlElement annotationlarini kullaniyoruz.
@XmlElement annotation’ini getter ya da setter metotta kullanabiliriz.
instance variable/property uzerine eklemek istiyorsak bu durumda @XmlRootElement annotationdan sonra @XmlAccessorType(XmlAccessType.FIELD) annotation’ini kullanmamiz gereklidir

Bir diger nokta olarak default constructor mevcut olmalidir.

package _23.jaxb.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

	@XmlElement
	private String id;
	@XmlElement
	private String name;
	@XmlElement
	private String surname;
	@XmlElement
	private String birthYear;

	public Person() {
		// default constructor zorunlu.
		// com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException:
		super();
	}

	public Person(String id, String name, String surname, String birthYear) {
		super();
		this.id = id;
		this.name = name;
		this.surname = surname;
		this.birthYear = birthYear;
	}

	//getters and setters
	...

}

PersonList.java

package _23.jaxb.model;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "person-list")
@XmlAccessorType(XmlAccessType.FIELD)
public class PersonList {

	@XmlElement(name = "person-definition")
	private List<Person> personList;
	
	public PersonList() {
		super();
	}

	public PersonList(List<Person> personList) {
		super();
		this.personList = personList;
	}

	//
	//getters and setters

	...
}

23.jaxb.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"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        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
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
        
        <context:component-scan base-package="_23.jaxb.controller" />
        <mvc:annotation-driven />
    
</beans>

web.xml

...
<init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>                                   
      <!--            
       /WEB-INF/01.appContext.xml
       /WEB-INF/02.00.appContext.xml
       /WEB-INF/03.multiActionController.xml      
       ...
      -->
       /WEB-INF/23.jaxb.xml
                                                      
      </param-value>                  
</init-param> 
... 

Ornegimizi calistirdigimizda ;

http://localhost:8080/injavawetrust.springmvc/getPersonXML

xml view

http://localhost:8080/injavawetrust.springmvc/getPersonListXML

xml view2

Way 2

Bir baska yaklasim olarak @ResponseBody annotation kullanmadan , XML yardimi ile benzer uygulamayi yapabiliriz. Farkli bir package uzerinde ornegimizi yapalim.

Oncelikle spring-oxm dependency tanimini pom.xml dosyamiza eklememiz gereklidir.

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-oxm</artifactId>
	<version>${spring.version}</version>
</dependency>

Employee.java

package _24.jaxb.oxm.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "employee")
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee {

	@XmlElement
	private String id;
	@XmlElement
	private String name;
	@XmlElement
	private String surname;
	@XmlElement
	private String birthYear;

	public Employee() {
		// default constructor zorunlu.
		// com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException:
		super();
	}

	public Employee(String id, String name, String surname, String birthYear) {
		super();
		this.id = id;
		this.name = name;
		this.surname = surname;
		this.birthYear = birthYear;
	}

	//getters and setters

}

EmployeeList.java

package _24.jaxb.oxm.model;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "employee-list")
@XmlAccessorType(XmlAccessType.FIELD)
public class EmployeeList {

	@XmlElement(name = "employee-definition")
	private List<Employee> personList;
	
	public EmployeeList() {
		super();
	}

	public EmployeeList(List<Employee> personList) {
		super();
		this.personList = personList;
	}

JAXBEmployeeController.java
Dikkat edecek olursak @ResponseBody annotation kullanmadik. Bir diger nokta olarak view name olarak marshallingView degerini verdik. Bu deger 24.jaxb.oxm.xml dosyasindaki bean id degerine karsilik gelecektir.

package _24.jaxb.oxm.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import _24.jaxb.oxm.model.Employee;
import _24.jaxb.oxm.model.EmployeeList;

@Controller
public class JAXBEmployeeController {

	@RequestMapping("/getEmployeeXML")
	// http://localhost:8080/injavawetrust.springmvc/getEmployeeXML
	public ModelAndView getEmployeeXML() {
		ModelAndView mv = new ModelAndView("marshallingView");
		mv.addObject(new Employee("1", "Levent", "Erguder", "1989"));
		return mv;
	}

	@RequestMapping("/getEmployeeListXML")
	// http://localhost:8080/injavawetrust.springmvc/getEmployeeListXML
	public ModelAndView getEmployeeListXML() {
		// prepare data
		Employee employee1 = new Employee("1", "Levent", "Erguder", "1989");
		Employee employee2 = new Employee("2", "James", "Gosling", "1955");
		Employee employee3 = new Employee("3", "Joshua", "Bloch", "1961");

		List<Employee> employees = new ArrayList<Employee>();
		employees.add(employee1);
		employees.add(employee2);
		employees.add(employee3);

		EmployeeList employeeList = new EmployeeList(employees);

		ModelAndView mv = new ModelAndView("marshallingView");
		mv.addObject(employeeList);
		return mv;
	}
}

24.jaxb.oxm.xml
MarshallingView ve Jaxb2Marshaller siniflarindan yararlaniyoruz. classesToBeBound property icin tanimladigimiz model siniflarimizi ekliyoruz.
Buradaki bean id degeri marshallingView , controller sinifimizdaki view bilgisine karsilik gelmektedir.

...
<context:component-scan base-package="_24.jaxb.oxm.controller" />

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />

<bean id="marshallingView"
	class="org.springframework.web.servlet.view.xml.MarshallingView">
	<constructor-arg>
		<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
			<property name="classesToBeBound">
				<list>
					<value>_24.jaxb.oxm.model.Employee</value>
					<value>_24.jaxb.oxm.model.EmployeeList</value>
				</list>
			</property>
		</bean>
	</constructor-arg>
</bean>
...

web.xml

...
<init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>                                   
      <!--            
       /WEB-INF/01.appContext.xml
       /WEB-INF/02.00.appContext.xml
       /WEB-INF/03.multiActionController.xml      
       ...
      -->
       /WEB-INF/24.jaxb.oxm.xml
                                                      
      </param-value>                  
</init-param> 
... 

Ornegimizi calistirdigimizda ;

http://localhost:8080/injavawetrust.springmvc/getEmployeeXML

xml view3

http://localhost:8080/injavawetrust.springmvc/getEmployeeListXML

Github kaynak kodlar / source folder
Injavawetrust-springmvc-tutorial

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *