GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Core Reflection Kết hợp Java Reflection và Java Annotations

Kết hợp Java Reflection và Java Annotations

Đăng vào 05/12/2017 . Được đăng bởi GP Coder . 6049 Lượt xem . Toàn màn hình

Java Reflection có thể nhận biết được những thứ (Class, field, method, ..) được chú thích bởi một Annotation nào đó. Và tất nhiên nó chỉ nhận biết được các Annotation có @Retention(RetentionPolicy.RUNTIME).

Reflection và Annotation là 2 tính năng rất mạnh mẽ của Java, nếu bạn hiểu rõ và vận dụng tốt nó sẽ giúp cho bạn tiết kiệm rất nhiều thời gian và công sức khi phải ngồi làm đi làm lại chỉ một công việc nhàm chán. Chẳng hạn như, bạn cần tính năng chuyển từ một đối tượng (object) sang xml. Nếu không có Reflection và Annotation thì ở mỗi đối tượng bạn đều phải viết code để chuyển đổi từ object sang xml.

Trong bài này tôi sẽ giới thiệu với các bạn cách kết hợp Java Reflection và Annotation để tạo chức năng chuyển một object sang xml.

Trong ví dụ này tôi sử dụng các class sau:

  • XmlRootElement: là một Annotation, sử dụng để đánh dấu phần tử gốc (root element) của một tài liệu xml.
  • XmlElementWrapper: là một Annotation sử dụng để đánh dấu đây là một phần cha và giá trị của nó là một Collection (có chứa tài liệu xml con).
  • XmlElement: là một Annotation, sử dụng để đánh dấu đây là một phần tử của tài liệu xml.
  • XmlAttribute: là một Annotation, sử dụng để đánh dấu đây là một thuộc tính của phần tử.
  • Book: lớp chứa thông tin sách.
  • BookStore: lớp chứa thông tin cửa hàng sách.
  • ObjectToXmlHelper: lớp sử dụng Reflection để đọc thông tin các Annotation được đánh dấu và chuyển sang tài liệu xml.
  • ObjectToXmlExample: chương trình minh họa sử dụng kết hợp Annotation với Reflection

Chi tiết code xử lý như sau:

Nội dung

  • 1 XmlRootElement.java
  • 2 XmlElementWrapper.java
  • 3 XmlElement.java
  • 4 XmlAttribute.java
  • 5 BookStore.java
  • 6 ObjectToXmlHelper.java
  • 7 ObjectToXmlExample.java

XmlRootElement.java


package com.gpcoder.combine;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.TYPE)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface XmlRootElement {
	
	String name();
	
	String namespace() default "";
	
}

XmlElementWrapper.java


package com.gpcoder.combine;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target({ ElementType.FIELD })
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface XmlElementWrapper {

	String name();

}

XmlElement.java

package com.gpcoder.combine;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target({ ElementType.FIELD })
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface XmlElement {

	String name();

}

XmlAttribute.java

package com.gpcoder.combine;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target({ ElementType.FIELD })
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface XmlAttribute {

	String name();

}

Book.java

package com.gpcoder.combine;

@XmlRootElement(name = "book")
public class Book {

	@XmlElement(name = "name")
	private String name;

	@XmlElement(name = "author")
	private String author;

	@XmlElement(name = "publisher")
	private String publisher;

	@XmlAttribute(name = "isbn")
	private String isbn;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getPublisher() {
		return publisher;
	}

	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}

	public String getIsbn() {
		return isbn;
	}

	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}

	@Override
	public String toString() {
		return "Book [name=" + name + ", author=" + author + ", publisher=" + publisher + ", isbn=" + isbn + "]";
	}

}

BookStore.java

package com.gpcoder.combine;

import java.util.List;

@XmlRootElement(name = "bookStore", namespace = "com.gpcoder.combine.annoation.reflection")
public class BookStore {

	@XmlElement(name = "name")
	private String name;

	@XmlElement(name = "location")
	private String location;

	@XmlElementWrapper(name = "bookList")
	private List<Book> bookList;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public List<Book> getBookList() {
		return bookList;
	}

	public void setBookList(List<Book> bookList) {
		this.bookList = bookList;
	}

	@Override
	public String toString() {
		return "BookStore [name=" + name + ", location=" + location + "]";
	}

}

ObjectToXmlHelper.java

package com.gpcoder.combine;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class ObjectToXmlHelper {

	/*
	 * Chuyển đối tượng sang chuỗi xml
	 */
	public static <T> String convertToXml(T obj) {
		StringBuilder sb = new StringBuilder();
		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
		sb.append(convertToXml(obj, 0));
		return sb.toString();
	}

	/*
	 * Chuyển đối tượng sang chuỗi xml
	 */
	private static <T> String convertToXml(T obj, int numOfTab) {
		StringBuilder sb = new StringBuilder();

		// Get Class of obj
		Class<?> clazz = obj.getClass();

		// Kiểm tra xem lớp này có được chú thích XmlRootElement hay không.
		boolean isXmlDoc = clazz.isAnnotationPresent(XmlRootElement.class);

		List<Field> fields;
		String name;
		String value;
		if (isXmlDoc) {
			// Lấy ra đối tượng XmlRootElement, chú thích trên lớp này.
			XmlRootElement rootNode = clazz.getAnnotation(XmlRootElement.class);

			sb.append(getTab(numOfTab)); // Add tab
			sb.append("<" + rootNode.name()); // Root element if (isNotEmpty(rootNode.namespace())) { sb.append(" xmlns=\"" + rootNode.namespace() + "\""); } fields = getFields(clazz, XmlAttribute.class); if (!fields.isEmpty()) { for (Field field : fields) { field.setAccessible(true); XmlAttribute ann = field.getAnnotation(XmlAttribute.class); name = ann.name(); value = getValueOfField(field, obj); sb.append(" " + name + "=\"" + value + "\""); // Add attribute } } sb.append("><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>");
			sb.append("\n"); // Add new line

			fields = getFields(clazz, null);
			if (!fields.isEmpty()) {
				// Create xml elements
				for (Field field : fields) {
					field.setAccessible(true);
					if (field.isAnnotationPresent(XmlElementWrapper.class)) {
						sb.append(createXmlWrapper(field, obj, numOfTab + 1));
					} else if (field.isAnnotationPresent(XmlElement.class)) {
						sb.append(createXmlElement(field, obj, numOfTab + 1));
					}
				}
			}

			sb.append(getTab(numOfTab));
			sb.append("</" + rootNode.name() + ">"); // End root element
		}

		return sb.toString();
	}

	private static String createXmlWrapper(Field field, Object obj, int numOfTab) {
		StringBuilder sb = new StringBuilder();
		XmlElementWrapper ann = field.getAnnotation(XmlElementWrapper.class);
		String name = ann.name(); // Get Element's name
		sb.append(getTab(numOfTab)); // Create 1 tab
		sb.append("<" + name + ">"); // Start Element
		sb.append("\n"); // Add new line
		Collection<?> collections = getListValueOfField(field, obj);
		if (collections != null && !collections.isEmpty()) {
			// Create xml sub elements
			for (Object collection : collections) {
				sb.append(convertToXml(collection, numOfTab + 1)); // Increase tab
				sb.append("\n"); // Add new line
			}
		}
		sb.append(getTab(numOfTab)); // Create 1 tab
		sb.append("</" + name + ">"); // End Element
		sb.append("\n"); // Add new line
		return sb.toString();
	}

	private static String createXmlElement(Field field, Object obj, int numOfTab) {
		StringBuilder sb = new StringBuilder();
		XmlElement ann = field.getAnnotation(XmlElement.class);
		String name = ann.name(); // Get Element's name
		String value = getValueOfField(field, obj); // Get value of field
		sb.append(getTab(numOfTab)); // Create tab
		sb.append("<" + name + ">"); // Start Element
		sb.append(value); // Element's content
		sb.append("</" + name + ">"); // End Element
		sb.append("\n"); // Add new line
		return sb.toString();
	}

	// Kiểm tra chuỗi không rỗng
	private static boolean isNotEmpty(String str) {
		return str != null && !str.isEmpty();
	}

	// Lấy danh sách field có sử dụng Annotation ann
	private static List<Field> getFields(Class<?> clazz, Class<? extends Annotation> ann) {
		List<Field> fieldAttributes = new ArrayList<>();

		Field[] fields = clazz.getDeclaredFields();
		if (ann == null) {
			fieldAttributes.addAll(Arrays.asList(fields));
		} else {
			for (Field field : fields) {
				if (field.isAnnotationPresent(ann)) {
					fieldAttributes.add(field);
				}
			}
		}

		return fieldAttributes;
	}

	// Lấy giá trị kiểu chuỗi
	private static String getValueOfField(Field field, Object obj) {
		String value = "";
		try {
			value = String.valueOf(field.get(obj));
		} catch (IllegalArgumentException | IllegalAccessException e) {
			e.printStackTrace();
		}
		return value;
	}

	// Lấy giá trị kiểu Collection (List, ArrayList, Set, ...)
	private static Collection<?> getListValueOfField(Field field, Object obj) {
		Collection<?> collection = null;
		try {
			Object objValue = field.get(obj);
			if (objValue instanceof Collection) {
				collection = (Collection<?>) objValue;
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			e.printStackTrace();
		}
		return collection;
	}

	// Lấy số dấu tab
	private static String getTab(int numOfTab) {
		StringBuilder sb = new StringBuilder();
		for (int i = 1; i <= numOfTab; i++) {
			sb.append("\t"); // Thêm dấu tab.
		}
		return sb.toString();
	}

}

ObjectToXmlExample.java


package com.gpcoder.combine;

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

public class ObjectToXmlExample {

	public static void main(String[] args) {
		// create list
		List<Book> bookList = new ArrayList<Book>();

		// create books
		Book book1 = new Book();
		book1.setIsbn("978-0-13-708189-9");
		book1.setName("Core Java Volume I");
		book1.setAuthor("Horstmann, Cay S. and Cornell");
		book1.setPublisher("Oracle");
		bookList.add(book1);

		Book book2 = new Book();
		book2.setIsbn("978-3832180577");
		book2.setName("Spring MVC Beginner’s Guide");
		book2.setAuthor("Amuthan G");
		book2.setPublisher("Packt Pub");
		bookList.add(book2);

		Book book3 = new Book();
		book3.setIsbn("999-1234567890");
		book3.setName("Java 8 in Action");
		book3.setAuthor("Raoul-Gabriel Urma");
		book3.setPublisher("Manning Publications Co.");
		bookList.add(book3);

		// create bookstore, assigning book
		BookStore bookStore = new BookStore();
		bookStore.setName("Fraport Bookstore");
		bookStore.setLocation("Frankfurt Airport");
		bookStore.setBookList(bookList);

		System.out.println(bookStore);
		System.out.println("bookList: ");
		for (Book book : bookList) {
			System.out.println("+ " + book);
		}

		System.out.println("\nConvert to xml: \n");
		String xml = ObjectToXmlHelper.convertToXml(bookStore);
		System.out.println(xml);
	}

}

Kết quả thực thi chương trình trên:


BookStore [name=Fraport Bookstore, location=Frankfurt Airport]
bookList: 
+ Book [name=Core Java Volume I, author=Horstmann, Cay S. & Cornell, publisher=Oracle, isbn=978-0-13-708189-9]
+ Book [name=Spring MVC Beginner’s Guide, author=Amuthan G, publisher=Packt Pub, isbn=978-3832180577]
+ Book [name=Java 8 in Action, author=Raoul-Gabriel Urma, publisher=Manning Publications Co., isbn=999-1234567890]

Convert to xml: 

<?xml version="1.0" encoding="UTF-8" ?>
<bookStore xmlns="com.gpcoder.combine.annoation.reflection">
	<name>Fraport Bookstore</name>
	<location>Frankfurt Airport</location>
	<bookList>
		<book isbn="978-0-13-708189-9">
			<name>Core Java Volume I</name>
			<author>Horstmann, Cay S. and Cornell</author>
			<publisher>Oracle</publisher>
		</book>
		<book isbn="978-3832180577">
			<name>Spring MVC Beginner’s Guide</name>
			<author>Amuthan G</author>
			<publisher>Packt Pub</publisher>
		</book>
		<book isbn="999-1234567890">
			<name>Java 8 in Action</name>
			<author>Raoul-Gabriel Urma</author>
			<publisher>Manning Publications Co.</publisher>
		</book>
	</bookList>
</bookStore>

Trên đây là ví dụ đơn giản minh họa việc kết hợp Reflection và Annotation trong các ứng dụng Java. Hy vọng giúp ích cho các bạn, hẹn gặp lại ở các bài viết tiếp theo.

5.0
17
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Reflection Được gắn thẻ: Annotation, Reflection

Hướng dẫn sử dụng Java Annotation
Hướng dẫn sử dụng Apache Maven với Eclipse

Có thể bạn muốn xem:

  • Hướng dẫn sử dụng Java Reflection (03/12/2017)
  • Marker Interface trong Java (30/03/2020)
  • Làm thế nào tạo instance của một class mà không gọi từ khóa new? (25/04/2019)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (97351 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (96986 lượt xem)
  • Giới thiệu Design Patterns (86648 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (85486 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83024 lượt xem)

Nội dung bài viết

  • 1 XmlRootElement.java
  • 2 XmlElementWrapper.java
  • 3 XmlElement.java
  • 4 XmlAttribute.java
  • 5 BookStore.java
  • 6 ObjectToXmlHelper.java
  • 7 ObjectToXmlExample.java

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link