Hiển thị các bài đăng có nhãn java. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn java. Hiển thị tất cả bài đăng

Thứ Năm, 26 tháng 12, 2013

Xử lý form trong Spring MVC

Trong phần này ta sẽ làm ví dụ xử lý dữ liệu lấy từ form ở trang JSP.
File->new->Spring project->Spring MVC Project
cấu trúc thư mục sẽ như sau:

Nội dung:
Sử dụng domain sau để lưu trữ thông tin của Product
package vn.ds.store.domains;

import java.io.Serializable;

public class Product implements Serializable {
 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 private String name;
 private String price;

 public String getName() {
  return name;
 }

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

 public String getPrice() {
  return price;
 }

 public void setPrice(String price) {
  this.price = price;
 }
}


Chương trình sẽ lấy dữ liệu khi người dùng nhập vào

 và in ra danh sách


dữ liệu nhập vào sẽ được validate như hình sau

Đầu tiên ta xây dựng file properties để lưu trữ thông báo cho chương trình.
file product-messages.properties sẽ được tạo ra ở thư mục src/main/resources

các parameter được tryền vào theo các vị trí {0} {1}...
Để spring đọc được file resources này ta định nghĩa thêm 1 bean  là thể hiện của lớp org.springframework.context.support.ReloadableResourceBundleMessageSource để đọc messages.
vào file WEB-INF/spring/appServlet/servlet-context.xml thêm đoạn sau:

  
 

Toàn bộ file servlet-context.xml sẽ như thế này:


 
 
 
 

 
 

 
 
  
  
 
 
 
 
 
  
 
 



Xong phần cấu hình, giờ sẽ xây dựng một lớp ProductValidator để valid dữ liệu từ người dùng. Vì spring đã hỗ trợ validate trong interface Validator nên class của ta chỉ việc implements giao diện đó và triển khai phương thức validate() của Validator interface.
package vn.ds.store.validators;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import vn.ds.store.domains.Product;

public class ProductValidator implements Validator {

 @Override
 public boolean supports(Class clazz) {

  return Product.class.isAssignableFrom(clazz);
 }

 @Override
 public void validate(Object target, Errors errors) {
  ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name",
    "msg.required", new Object[] { "name" });
  ValidationUtils.rejectIfEmptyOrWhitespace(errors, "price",
    "msg.required", new Object[] { "price" });
  Product product = (Product) target;
  String name = product.getName();
  int max = 6;
  if (!name.isEmpty() && name.length() > max)
   errors.rejectValue("name", "msg.maxlength", new Object[] { "name",
     max }, "");
  if (!isNumber(product.getPrice().trim()))
   errors.rejectValue("price", "msg.number", new Object[] { "price",
     max }, "");
 }

 public boolean isNumber(String s) {
  for (int i = 0; i < s.length(); i++) {
   if (!Character.isDigit(s.charAt(i)))
    return false;
  }
  return true;
 }

}


Phương thức
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name",
    "msg.required", new Object[] { "name" });
sẽ kiểm tra xem trường "name" có emty hay có space không, nếu có sẽ add thêm một message vào đối tượng errors, nội dung msg sẽ được lấy theo id của msg trong resources là "msg.required" và truyền vào một parameter cho msg đó là một mảng Object có 1 phần tử là "name". Tương tự phương thức
errors.rejectValue("price", "msg.number", new Object[] { "price",
     max }, "");
cũng sẽ add thêm một msg của trường "price" vào errors theo msg là "msg.number" và set vào 2 parameter là một biến String "price" và một biến Integer max
Controller
package vn.ds.store.controllers;

import java.util.ArrayList;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import vn.ds.store.domains.Product;
import vn.ds.store.validators.ProductValidator;

@Controller
@RequestMapping("product")
public class ProductController {

 private ProductValidator validator = new ProductValidator();

 @RequestMapping(value = "create", method = RequestMethod.GET)
 public String doGet(Model model) {
  model.addAttribute("product", new Product());
  return "createProduct";
 }

 @RequestMapping(value = "save", method = RequestMethod.POST)
 public String doPost(@ModelAttribute Product product,
   Model model, BindingResult errors) {
  validator.validate(product, errors);
  if (errors.hasErrors()) {
   return "createProduct";
  }
  ArrayList lst = new ArrayList();
  Product p = new Product();
  p.setName("product 1");
  p.setPrice("100");
  lst.add(p);
  lst.add(product);
  model.addAttribute("products", lst);
  return "listProduct";
 }
}


Ở đây Phương thức GET của url "/product/create" sẽ được xử lý bởi hàm doGet(). hàm này sẽ tạo mới một đối tượng Product và add vào model. sau đó trả về một view có tên là "createProduct". view này là view jsp được định nghĩa trong file servlet-context.xml. vì ta không định nghĩa cụ thể nên spring sẽ xem id của view theo tên file jsp. Phương thức POST của url "/product/save" sẽ xử lý khi người dụng submit form trong method doPost()
Đầu tiên sẽ validate dữ liệu theo đối tượng ProductValidator. nếu có lỗi sẽ trả về view "createProduct" là trang nhập dữ liệu
Nếu không có lỗi sẽ thực hiện add dữ liệu vào model và gửi xuống view "listProduct".
JSP
file createProduct.jsp trong thư mục WEB-INF/views sẽ như sau:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>




Insert title here



 
  
create
Name
Price
 

và view hiển thị danh sách listProduct.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>   




Insert title here



 
List of products
Name Price
${p.name} ${p.price}

Source code theo link http://www.mediafire.com/download/vki3lvwpsqtpam8/Store_handling_form.rar Thanks & Rgds!!!

Thứ Tư, 25 tháng 12, 2013

Hướng dẫn sử dụng Spring Tool Suice (STS)

Spring Tool Suice (STS) là một plugin cho Eclipse hỗ trợ dev phát triển các project dựa trên Spring framework
http://spring.io/tools/sts
Bài viết này sẽ hướng dẫn cách sử dụng STS
Trên thanh công cụ của Eclipse->Help->EclipseMarketplace
Gõ vào ô tìm kiếm với từ khóa STS
Chọn STS phù hợp với phiên bản Eclipse-> Install


Sau khi eclipse hoàn tất cài đặt và khởi động lại
cần phải bỏ valid derived query để tránh các cảnh báo lỗi không cần thiết
Window->Preferences->Spring.
ở tab Project validators->Data validator và bỏ check  ở Invalid Derived Query-> OK

Create một project Spring web MVC

File->New->Spring Project->Spring MVC Project

Nhập tên package và Finish



STS sẽ tự động tạo một project mẫu với một controller Home

Nếu Project bị lỗi, là do version của spring đó không còn maven không hỗ trợ để load thư viện về.
để sửa bạn vào file pom.xml. chọn properties của spring và thay bằng version khác (có thể tham khảo tại http://mvnrepository.com/artifact/org.springframework)


Sau đó save lại, và chọn Project->clean.
bây giờ click phải chuột vào Store->Run As
và xem kết quả!

Bây giờ hãy xem lại example vừa được tạo ra
cấu trúc thư mục sẽ như thế này

Một ứng dụng spring MVC sẽ theo đúng mô hình MVC chuẩn, ta quan tâm đến các file sau: HomeController.java, web.xml, servlet-context.xml

HomeController.java
package vn.ds.store;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
 
 private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
 
 /**
  * Simply selects the home view to render by returning its name.
  */
 @RequestMapping(value = "/", method = RequestMethod.GET)
 public String home(Locale locale, Model model) {
  logger.info("Welcome home! The client locale is {}.", locale);
  
  Date date = new Date();
  DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
  
  String formattedDate = dateFormat.format(date);
  
  model.addAttribute("serverTime", formattedDate );
  
  return "home";
 }
 
}


Controller này sẽ xử lý request cho ull "/"  và trả về một view có tên là "home"

web.xml


 
 
  contextConfigLocation
  /WEB-INF/spring/root-context.xml
 
 
 
 
  org.springframework.web.context.ContextLoaderListener
 

 
 
  appServlet
  org.springframework.web.servlet.DispatcherServlet
  
   contextConfigLocation
   /WEB-INF/spring/appServlet/servlet-context.xml
  
  1
 
  
 
  appServlet
  /
 
Ứng dụng Spring sẽ được xoay quanh một servlet trung tâm là DispatcherServlet, các request khi yêu cầu đến ứng dụng đều được servlet này xử lý sau đó lựa chọn controller xử lý và trả về model and view nào phù hợp
Các request sẽ được xử lý theo url-mapping là "/"
ở đây bạn có thể sửa url để DispatcherServlet xử lý  như .html, .do, .xxx ....
Servlet-context.xml


 
 
 
 

 
 

 
 
  
  
 
 
 
 
 
 


Dòng <annotation-driven /> sẽ cho phép sử dụng các @notation, đây là một đặc điểm của spring kể từ spring 3 trở đi
các phương thức GET yêu cầu resources(image, js, css..) sẽ được khai báo bởi dòng
<resources mapping="/resources/**" location="/resources/" />
Khai báo viewResolver là jsp ở dòng
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
Có thể khai báo nhiều viewResolver khác như pdf, excel...
Cuối cùng dòng
<context:component-scan base-package="vn.ds.store" />
sẽ cho phép quét các class được khai báo là controller (bởi anotation @Controller) ở trong package được chỉ ra, ở đây là vn.ds.store
Tương tự bạn có thể tạo ra nhiều controller khác  để xử lý các nghiệp vụ khác nhau trong package đó, và tạo file jsp trong /WEB-INF/views/ để hiển thị.

Thks & Rgds!

Thứ Tư, 18 tháng 12, 2013

Class xử lý Date trong java

Việc xử lý kiểu Date trong java khá phức tạp, nhiều khi làm cho dev rất mất thời gian.
đây là class chứa một số hàm cơ bản thao tác trên kiểu Date
(sử dụng thêm thư viện joda-time của java)
http://www.joda.org/joda-time/


package test;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.Years;
import org.joda.time.format.DateTimeFormat;

public class DateUtil {
 private static SimpleDateFormat simpleDateFormat;

 /**
  * get String of system date
  * 
  * @param format
  * @return String
  */
 public static String getSystemDateString(String format) {
  simpleDateFormat = new SimpleDateFormat(format);
  return simpleDateFormat.format(new Date());
 }

 /**
  * convert Date to String
  * 
  * @param date
  * @param format
  * @return String of date
  */
 public static String convertDateToString(Date date, String format) {
  if (null == date) {
   return null;
  }
  simpleDateFormat = new SimpleDateFormat(format);
  return simpleDateFormat.format(date);
 }

 /**
  * convert String to date
  * 
  * @param dateString
  * @param format
  * @return date
  */
 public static Date convertStringToDate(String dateString, String format) {
  if (null == dateString || "".equals(dateString.trim())) {
   return null;
  }
  return DateTime.parse(dateString, DateTimeFormat.forPattern(format))
    .toDate();
 }

 /**
  * calculate age
  * 
  * @param birthday
  * @return age
  */
 public static int calculateAge(Date birthday) {
  DateTime dtBirthday = new DateTime(birthday);
  DateTime now = new DateTime();
  Years age = Years.yearsBetween(dtBirthday, now);
  return age.getYears();
 }

 /**
  * add num day into date
  * 
  * @param number
  * @param date
  * @return added date
  */
 public static Date addingDays(int number, Date date) {
  DateTime dt = new DateTime(date);
  return dt.plusDays(number).toDate();
 }

 public static void main(String[] args) {
  String format = "dd/MM/yyyy";
  String dateString = "28/02/1991";
  Date date = null;
  Date now = new Date();
  System.out.println(getSystemDateString(format));
  date = convertStringToDate(dateString, format);
  System.out.println(date.toString());
  System.out
    .println(calculateAge(convertStringToDate(dateString, format)));
  System.out.println(convertDateToString(now, format));
  System.out.println("after adding: ");
  System.out.println(convertDateToString(addingDays(-90, now), format));
  System.out.println(convertDateToString(addingDays(20, now), format));
 }
}

Thứ Năm, 26 tháng 9, 2013

Demo Job Scheduler sử dụng Quartz

maven dependences

    log4j
    log4j
    1.2.17
   
   
    org.quartz-scheduler
    quartz
    2.0.2
   

Xây dựng lớp TestJob implement Job của Quartz. lớp này để thực hiện một công việc mà ta cần làm sau một khoảng thời gian xác định. Cụ thể công việc ở đây là in ra dòng thông báo.
package vn.diepviends.job;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class TestJob implements Job {
 private Logger log = Logger.getLogger(TestJob.class);
 public void execute(JobExecutionContext arg0) throws JobExecutionException {
  log.debug("Test job run successfully after 2s");    
 }

}
Trong lớp chính cần gọi ta cài đặt khoảng thời gian lặp lại cho job và gọi TestJob class để thực hiện
package vn.diepviends.job;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class JobScheduler {
 public static void main(String[] args) {
  try {

   // chi ra job can thuc hien
   JobDetail job = JobBuilder.newJob(TestJob.class)
     .withIdentity("testJob").build();

   // qui dinh thoi gian la 2s, lap lai mai mai
   Trigger trigger = TriggerBuilder
     .newTrigger()
     .withSchedule(
       SimpleScheduleBuilder.simpleSchedule()
         .withIntervalInSeconds(2).repeatForever())
     .build();

   // start
   SchedulerFactory schFactory = new StdSchedulerFactory();
   Scheduler sch = schFactory.getScheduler();
   sch.start();
   sch.scheduleJob(job, trigger);   

  } catch (SchedulerException e) {
   e.printStackTrace();
  }
 }
}
Và đây là kết quả khi run lớp JobScheduler


Cấu trúc chương trình:

Thứ Năm, 11 tháng 7, 2013

sử dụng JSON

kiến thức cơ bản về JSON:
Tiếng việt: http://www.qhonline.info/forum/showthread.php/4373-json-la-gi-json-lam-viec-nhu-the-nao-phan-1
w3school: http://www.w3schools.com/json/

Để sử dụng JSON trong java có thể dùng nhiều lib khác nhau như json.simple hoặc net.sf.json.
mình dùng cái thứ 2 net.sf.json. link : http://json-lib.sourceforge.net/
web hỗ trợ view json data online: http://www.jsoneditoronline.org/
ví dụ json data sau:
{
    "id": "s01",
    "name": "student1",
    "marks": [
        {
            "subject": "Toán",
            "mark": "9"
        },
        {
            "subject": "Hoá",
            "mark": "10"
        }
    ]
}
Parsing json data trên trong java:
String jsonStr = "{\"id\":\"s01\",\"name\":\"student1\",\"marks\":[{\"subject\":\"Toán\",\"mark\":\"9\"},{\"subject\":\"Hoá\",\"mark\":\"10\"}]}";
   JSONObject student = JSONObject.fromObject(jsonStr);
   System.out.println("ID: " + student.getString("id"));
   System.out.println("Name: " + student.getString("name"));
   System.out.println("Marks: ");
   JSONArray marks = student.getJSONArray("marks");
   Iterator it = marks.iterator();
   while(it.hasNext()) {
    JSONObject m = (JSONObject)it.next();
    System.out.println("subject: " + m.getString("subject"));
    System.out.println("mark: " + m.getString("mark"));
   }
Tạo một json data trong java:
JSONObject json = new JSONObject();
  json.put("id", "s01");
  json.put("name", "student1");
  System.out.println(json);
Nếu hiển thị trên web thì sử dụng javascript để phân tích json là tốt nhất. Javascript xem một json data là một object, và trong object đó có sẽ có nhiều object khác được định nghĩa.
 function start(temp){
  document.write(createTemplate(temp));
 }
 function doClick(id,obj) {
  getJson(id,obj); 
  $(obj).attr('onclick','expand(this)');
  $(obj).attr('src','images/minus.jpg');  
 
 }
 function expand(obj)
 {  
  if ($(obj).parent().find("ul").length>0) {   
   if($(obj).hasClass("expanded")) {
    $(obj).parent().children("ul").show();
    $(obj).removeClass("expanded");
    $(obj).attr('src','images/minus.jpg');
   } 
   else {
    $(obj).parent().children("ul").hide();
    $(obj).addClass("expanded");
    $(obj).attr('src','images/plus.png');
   }
  }
 }

 function createTemplate(temp) {
  var html;
  html = "
  • id: " + temp.id + ""; for ( var act in temp.actions) { html += "
    • action: " + temp.actions[act].action + "
    • "; html += "
    • type: "+ temp.actions[act].type +"
    • "; html += "
    • params
        "; for(var pa in temp.actions[act].params) { html += "
      • name: " + temp.actions[act].params[pa].name + "
      • "; html += "
      • data: " + temp.actions[act].params[pa].data + "
      • "; } html += "
    • "; } for ( var lnk in temp.links) { var x = temp.links[lnk].linkId; if(temp.links[lnk].hasOwnProperty("params") && temp.links[lnk].params.length > 0){ html += "
    • " + temp.links[lnk].params[0].name + ": " + temp.links[lnk].params[0].data; html += "
    •  link: " + x + "
    • "; } else{ html += "
    •  link: " + x + "
    • "; } } html += "
    "; return html; } function setId(id1,id2) { if(id1 == id2) return "none"; else return id2; }