Restful Webservice Upload file kèm dữ liệu JSON sử dụng Jersey trong Java và Oracle
Đăng lúc: 09:47 AM - 27/11/2023 bởi Charles Chung - 1094Trong bài này tôi sẽ hướng dẫn các bạn tạo ứng dụng RESTful Web Service Upload file kèm dữ liệu JSON sử dụng thư viện Jersey trong Eclipse. CRUD OnetoMany Relationship với Database Oracle sử dụng Hibernate
Chuẩn bị dữ liệu
- Tạo cơ sở dữ liệu "bkap" trong Oracle
- Tạo bảng "Departments" và "Employees" trong bkap database (xem file bkap.sql đính kèm trong source code project)
Tạo ứng dụng RESTfule Webservice
Bước 1: Tạo Dynamic Web Project (xem chi tiết bài Phát triển ứng dụng RESTful Web Service trong Java với thư viện Jersey )
- Khởi động Eclispe IDE -> vào menu File -> New -> Dynamic Web Project -> Nhập tên "RestfulWeberviceJerseyUploadFileOracle"
- Tiêp tục kích vào Next -> Next -> Chọn Generate web.xml deyployment desciptor
Bước 2: Convert sang Maven Project
- Kích chuột phải vào Project vừa tạo -> Configure -> Convert to Maven Project -> Finish
Bước 3: Khai báo các Maven Dependencies cần thiết
- Mở file pom.xml và cấu hình các Maven Dependencies gồm: jersey server, jersey upload file, gson, hibernate, oracle, jaxb api
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.26.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc10 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc10</artifactId>
<version>19.20.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-server -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
Bước 4: Cấu hình ứng dụng Jersey Servlet
- Mở tệp web.xml và cấu hình vào bên trong thẻ <web-app> như sau:
<servlet>
<servlet-name>jerseyServlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>hanam88.services</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jerseyServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Bước 5: Tạo các package và các class theo cấu trúc sau
- Tệp cấu hình hibernate.cfg.xml (xem bài trước Tạo RESTful Web Service trong Java với Jersey và Oracle)
- Tạo lớp hanam88.entities\Department.java (mapped với bảng Departments trong database)
package hanam88.entities;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="departments")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="departmentid")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int departmentId;
@Column(name="departmentname")
private String departmentName;
@Column(name="active")
private int active;
// @OneToMany(mappedBy = "department", fetch = FetchType.EAGER)
// private Set<Employee> employees;
public Department() {
// TODO Auto-generated constructor stub
}
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public int getActive() {
return active;
}
public void setActive(int active) {
this.active = active;
}
}
- Tạo lớp hanam88.entities\Employee.java (mapped với bảng Employees trong database)
package hanam88.entities;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="employees")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="employeeid")
private String employeeId;
@Column(name="fullname")
private String fullName;
@Column(name="birthday")
@Temporal(TemporalType.DATE)
private Date birthDay;
@Column(name="picture")
private String picture;
@Column(name="gender")
private int gender;
@Column(name="address")
private String address;
@Column(name="phone")
private String phone;
@Column(name="email")
private String email;
@Column(name="departmentid")
private int departmentId;
@Column(name="active")
private int active;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "departmentId", insertable = false, updatable = false)
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Employee() {
// TODO Auto-generated constructor stub
}
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Date getBirthDay() {
return birthDay;
}
public void setBirthDay(Date birthDay) {
this.birthDay = birthDay;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public int getActive() {
return active;
}
public void setActive(int active) {
this.active = active;
}
}
- Tạo lớp hanam88.entities\EmployeeResult.java (Biểu diễn dữ liệu join từ hai bảng Departments và Employees trong database)
package hanam88.entities;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
public class EmployeeResult implements Serializable {
private static final long serialVersionUID = 1L;
private String employeeId;
private String fullName;
@Temporal(TemporalType.DATE)
private Date birthDay;
private String picture;
private int gender;
private String phone;
private String email;
private String departmentName;
public EmployeeResult() {
// TODO Auto-generated constructor stub
}
public EmployeeResult(String employeeId, String fullName, Date birthDay, String picture, int gender, String phone,
String email, String departmentName) {
super();
this.employeeId = employeeId;
this.fullName = fullName;
this.birthDay = birthDay;
this.picture = picture;
this.gender = gender;
this.phone = phone;
this.email = email;
this.departmentName = departmentName;
}
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Date getBirthDay() {
return birthDay;
}
public void setBirthDay(Date birthDay) {
this.birthDay = birthDay;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
}
- Tạo lớp hanam88.entities\Result.java (Biểu diễn kết quả trả về client-xem bài trước Tạo RESTful Web Service trong Java với Jersey và Oracle)
- Tạo lớp hanam88.dao\HibernateUtil.java (đọc thông tin cấu hình trong tệp hibernate.cfg.xml và tạo sessionfactory-xem bài trước Tạo RESTful Web Service trong Java với Jersey và Oracle)
- Tạo interface hanam88.dao\GenericDAO.java
package hanam88.dao;
import java.util.List;
public interface GenericDAO<T,K> {
public List<T> getAll();
public T getById(K id);
public T add(T obj);
public T update(T obj);
public T remove(K id);
}
- Tạo interface hanam88.dao\DepartmentDAO.java
package hanam88.dao;
import java.util.List;
import hanam88.entities.Department;
import hanam88.entities.Employee;
public interface DepartmentDAO extends GenericDAO<Department, Integer> {
public List<Employee> getEmployees(int depid);
}
- Tạo interface hanam88.dao\EmployeeDAO.java
package hanam88.dao;
import java.util.List;
import hanam88.entities.Employee;
import hanam88.entities.EmployeeResult;
public interface EmployeeDAO extends GenericDAO<Employee, String> {
List<EmployeeResult> getEmployeeFull();
}
- Tạo lớp hanam88.dao\DepartmentImpl.java
package hanam88.dao;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import hanam88.entities.Department;
import hanam88.entities.Employee;
public class DepartmentImpl implements DepartmentDAO {
SessionFactory sf = HibernateUtil.getSessionFactory();
@Override
public List<Department> getAll() {
Session session = sf.openSession();
List<Department> data = new ArrayList<>();
Query query = session.createQuery("from Department");
data = query.getResultList();
session.close();
return data;
}
@Override
public Department getById(Integer id) {
Session session = sf.openSession();
Department data = session.find(Department.class, id);
session.close();
return data;
}
@Override
public Department add(Department obj) {
Session session = sf.openSession();
session.beginTransaction();
session.save(obj);
session.getTransaction().commit();
session.close();
return obj;
}
@Override
public Department update(Department obj) {
Session session = sf.openSession();
session.beginTransaction();
session.update(obj);
session.getTransaction().commit();
session.close();
return obj;
}
@Override
public Department remove(Integer id) {
Session session = sf.openSession();
session.beginTransaction();
Department data = session.find(Department.class, id);
if(data!=null)
session.remove(data);
session.getTransaction().commit();
session.close();
return data;
}
@Override
public List<Employee> getEmployees(int depid) {
Session session = sf.openSession();
List<Employee> data = new ArrayList<>();
Query query = session.createQuery("from Employee where departmentId=:depid").setParameter("depid", depid);
data = query.getResultList();
session.close();
return data;
}
}
- Tạo lớp hanam88.dao\EmployeeImpl.java
package hanam88.dao;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import hanam88.entities.Employee;
import hanam88.entities.EmployeeResult;
public class EmployeeImpl implements EmployeeDAO {
SessionFactory sf = HibernateUtil.getSessionFactory();
@Override
public List<Employee> getAll() {
Session session = sf.openSession();
List<Employee> data = new ArrayList<>();
Query query = session.createQuery("from Employee");
data = query.getResultList();
session.close();
return data;
}
@Override
public Employee getById(String id) {
Session session = sf.openSession();
Employee data =session.find(Employee.class,id);
session.close();
return data;
}
@Override
public Employee add(Employee obj) {
Session session = sf.openSession();
session.beginTransaction();
session.save(obj);
session.getTransaction().commit();
session.close();
return obj;
}
@Override
public Employee update(Employee obj) {
Session session = sf.openSession();
session.beginTransaction();
session.update(obj);
session.getTransaction().commit();
session.close();
return obj;
}
@Override
public Employee remove(String id) {
Session session = sf.openSession();
session.beginTransaction();
Employee data =session.find(Employee.class,id);
session.delete(data);
session.getTransaction().commit();
session.close();
return data;
}
@Override
public List<EmployeeResult> getEmployeeFull() {
Session session = sf.openSession();
List<EmployeeResult> result = new ArrayList<>();
Query query = session.createQuery("select e.employeeId, e.fullName, e.birthDay,e.picture,e.gender, e.phone, e.email,d.departmentName from Employee e inner join Department d on e.departmentId = d.departmentId");
List<Object[]> data = query.getResultList();
for (Object[] e : data) {
try {
result.add(new EmployeeResult(e[0].toString(),e[1].toString(),new SimpleDateFormat("yyyy-MM-dd").parse(e[2].toString()),e[3].toString(),Integer.valueOf(e[4].toString()),e[5].toString(),e[6].toString(),e[7].toString()));
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
session.close();
return result;
}
}
- Tạo lớp service hanam88.services\DepartmentService.java
package hanam88.services;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import hanam88.dao.DepartmentDAO;
import hanam88.dao.DepartmentImpl;
import hanam88.entities.Department;
import hanam88.entities.Result;
import com.google.gson.Gson;
@Path("/departments")
public class DepartmentService {
DepartmentDAO dao = new DepartmentImpl();
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public String getDepartments() {
var gson = new Gson();
return gson.toJson(dao.getAll());
}
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String getDepartment(@PathParam("id") int id) {
var gson = new Gson();
return gson.toJson(dao.getById(id));
}
@GET
@Path("/employees/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String getEmployees(@PathParam("id") int id) {
var gson = new Gson();
var dep = dao.getEmployees(id);
if (dep != null)
return gson.toJson(dep);
else
return gson.toJson(new Result(200, "Không tìm thấy phòng ban"));
}
@POST
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public String post(String dep) {
var gson = new Gson();
var department = gson.fromJson(dep, Department.class);
dao.add(department);
return gson.toJson(new Result(200, "Thêm thành công"));
}
@PUT
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public String post(@PathParam("id") int id, String dep) {
var gson = new Gson();
var department = gson.fromJson(dep, Department.class);
if (department.getDepartmentId() == id) {
dao.update(department);
return gson.toJson(new Result(200, "Sửa thành công"));
} else {
return gson.toJson(new Result(404, "Mã số không khớp"));
}
}
@DELETE
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String delete(@PathParam("id") int id) {
var gson = new Gson();
var dep = dao.remove(id);
if (dep != null)
return gson.toJson(new Result(200, "Xóa thành công"));
else
return gson.toJson(new Result(200, "Không tìm thấy phòng ban cần xóa"));
}
}
- Tạo lớp service hanam88.services\EmployeeService.java
package hanam88.services;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import hanam88.dao.EmployeeDAO;
import hanam88.dao.EmployeeImpl;
import hanam88.entities.Employee;
import hanam88.entities.Result;
@Path("/employees")
public class EmployeeService {
EmployeeDAO dao = new EmployeeImpl();
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public String getEmployees() {
var gson = new GsonBuilder().setDateFormat("dd/MM/yyyy").create();
return gson.toJson(dao.getAll());
}
@GET
@Path("/full")
@Produces(MediaType.APPLICATION_JSON)
public String getEmployeeFull() {
var gson = new GsonBuilder().setDateFormat("dd/MM/yyyy").create();
return gson.toJson(dao.getEmployeeFull());
}
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String getEmployees(@PathParam("id") String id) {
var gson = new GsonBuilder().setDateFormat("dd/MM/yyyy").create();
var emp = dao.getById(id);
if (emp != null)
return gson.toJson(emp);
else
return gson.toJson(new Result(200, "Không tìm thấy nhân viên"));
}
@POST
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({ MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_JSON })
public String post(@FormDataParam("emp") String emp, @FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail, @Context ServletContext servletContext) {
String picture=null;
if (fileDetail != null) {
// lấy tên tệp tin
String filename = fileDetail.getFileName();
// lấy đường dẫn thư mục images trên server
String pathimages = servletContext.getRealPath("images");
picture="/images/"+filename;
// gọi hàm lưu tệp upload
writeToFile(uploadedInputStream, pathimages + "\\" + filename);
}
// chuyển đổi json sang object
var gson = new GsonBuilder().setDateFormat("dd/MM/yyyy").create();
var employee = gson.fromJson(emp, Employee.class);
// set giá trị cho picture
employee.setPicture(picture);
// lưu
dao.add(employee);
return gson.toJson(new Result(200, "Thêm thành công"));
}
// Lưu tệp tin vào vị trí upload
private void writeToFile(InputStream uploadedInputStream, String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@PUT
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({ MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_JSON })
public String post(@PathParam("id") String id, @FormDataParam("emp") String emp,
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail, @Context ServletContext servletContext) {
String picture=null;
if (fileDetail != null) {
// lấy tên tệp tin
String filename = fileDetail.getFileName();
// lấy đường dẫn thư mục images trên server
String pathimages = servletContext.getRealPath("images");
picture="/images/"+filename;
// gọi hàm lưu tệp upload
writeToFile(uploadedInputStream, pathimages + "\\" + filename);
}
// chuyển đổi json sang object
var gson = new GsonBuilder().setDateFormat("dd/MM/yyyy").create();
var employee = gson.fromJson(emp, Employee.class);
// set giá trị cho picture
if(picture!=null)
employee.setPicture(picture);
if (employee.getEmployeeId().equals(id)) {
dao.update(employee);
return gson.toJson(new Result(200, "Sửa thành công"));
} else {
return gson.toJson(new Result(404, "Mã số không khớp"));
}
}
@DELETE
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public String delete(@PathParam("id") String id) {
var gson = new Gson();
var emp = dao.remove(id);
if (emp != null)
return gson.toJson(new Result(200, "Xóa thành công"));
else
return gson.toJson(new Result(200, "Không tìm thấy nhân viên cần xóa"));
}
}
Bước 6: Run application
- Kích chuột phải vào project chọn Run As -> Run on Server -> Tomcat v9.0
- Mở phần mềm Postman để test
- GET: api/employees (trả về danh sách nhân viên kèm theo phòng ban)
- POST: api/employees (thêm nhân viên kèm upload ảnh)
Video demo
Link download source code bài viết Restful Webservice Upload file kèm dữ liệu JSON sử dụng Jersey trong Java và Oracle
thay lời cảm ơn!
Các bài cũ hơn
- Tạo RESTful Web Service trong Java với Jersey và Oracle (10:41 AM - 24/11/2023)
- Phát triển ứng dụng RESTful Web Service trong Java với thư viện Jersey (12:52 PM - 22/11/2023)
- Tổng hợp các câu hỏi phỏng vấn về Spring Core-Spring MVC (09:36 AM - 21/11/2023)
- Microservices sử dụng ASP.NET Core 6 và Deploy với Docker (08:41 AM - 20/11/2023)
- Đọc thông tin Metadata Attribute của Controller và Action trong ASP.NET Core 6 sử dụng Reflection (08:35 AM - 15/11/2023)