Để bổ sung hỗ trợ kiểm tra Selen vào ứng dụng của bạn, hãy thực hiện các lệnh sau: selenium test --controller ~.web.SpeakerController selenium test --controller ~.web.TalkController Lệ
Trang 1Giới thiệu Spring Roo, Phần 2: Phát triển một ứng
dụng bằng Spring Roo
Để mở rộng ứng dụng hội nghị của mình, chúng ta cần tạo lại ứng dụng đó từ Phần 1 Bạn có thể làm theo các hướng dẫn trước hoặc sử dụng lệnh script (tạo kịch bản lệnh) của Roo Lệnh
script thực hiện tất cả các lệnh đã quy định trong một tệp tài nguyên Nếu bạn đã làm theo Phần 1, bạn đã nhận thấy rằng Roo đã tạo ra một tệp tên là log.roo, có tất cả các lệnh thực hiện trên trình vỏ Roo Chúng ta sẽ thực hiện tệp log.roo đó và tạo lại ứng dụng này
1 Tệp này được bao gồm trong mã mẫu Bạn có thể đổi tên nó là conference.roo
2 Tạo một thư mục mới có tên là conference và sao chép conference.roo vào thư mục đó
3 Mở trình vỏ dòng lệnh của hệ điều hành của bạn
4 Chuyển đến thư mục conference mà bạn vừa tạo ra
5 Thực hiện lệnh script file conference.roo
Lệnh script sẽ tạo lại ứng dụng trong một vài giây nếu bạn có các JAR cần thiết trong kho lưu trữ Maven của mình Nếu không, sẽ mất nhiều thời gian hơn vì nó phải tải về tất cả các JAR Lệnh script rất có ích theo cách bạn có thể sử dụng nó như một khuôn mẫu để tạo ra các dự án
do Spring quản lý
Trước khi chúng ta tiến lên, hãy nhập khẩu dự án Maven bằng STS STS có đóng gói sẵn với
trình cắm thêm Eclipse Maven Bạn nên nhập khẩu dự án này bằng cách chọn File > Import >
Maven > Existing Maven Projects (Các dự án Maven hiện có), sau đó chọn thư mục của dự án
Chúng ta sẽ nhập khẩu dự án này bằng STS khi chúng ta sẽ viết một số mã tùy chỉnh sau
Ứng dụng web mà chúng ta đã tạo ra cho đến nay vẫn hoạt động và chúng ta có thể kiểm tra nó bằng thủ công nhờ tạo, đọc, cập nhật và xóa các thực thể Speaker (Người nói) và Talk (Cuộc thảo luận) Nhưng nó sẽ không còn thú vị nữa phải không nếu chúng ta đã có thể tự động hoá quá trình này?
Về đầu trang
Kiểm tra web được tự động hóa
Ở đây có kèm tính năng tiếp theo của Spring Roo là: hỗ trợ kiểm tra Selen Selen là một tập các công cụ rất mạnh hỗ trợ sự phát triển nhanh về tự động hóa kiểm tra cho các ứng dụng dựa trên web Để bổ sung hỗ trợ kiểm tra Selen vào ứng dụng của bạn, hãy thực hiện các lệnh sau:
selenium test controller ~.web.SpeakerController
selenium test controller ~.web.TalkController
Lệnh selenium test sẽ tạo ra bài kiểm tra Selen cho các bộ điều khiển Speaker và Talk Lệnh
này có một thuộc tính bắt buộc tên là controller (bộ điều khiển) để chỉ rõ tên của bộ điều khiển
để tạo ra bài kiểm tra Selen Lệnh này cũng có hai thuộc tính tuỳ chọn tên là name và serverUrl
Trang 2để chỉ rõ tên của bài kiểm tra Selen và máy chủ nơi ứng dụng web có sẵn Spring Roo cũng sẽ bổ sung trình cắm thêm Selenium Maven khi bạn thực hiện lệnh selenium test
Ở trên, chúng ta đã tạo ra các trường hợp kiểm tra Selen cho bộ điều khiển của mình, nhưng trước khi chạy chúng, chúng ta cần phải sửa chữa một lỗi nhỏ trong bộ kiểm tra Selen do Spring Roo tạo ra Chúng ta đã thêm một ràng buộc trong thực thể Speaker của mình là tuổi nên ở giữa
25 và 60, nhưng bộ kiểm tra này không lưu tâm đến ràng buộc đó Nó đã sử dụng một giá trị tuổi
là 1, do đó, việc kiểm tra sẽ thất bại Chúng ta cần sửa đổi một tệp có tên là test-speaker.xhtml và cập nhật tệp này như trong Liệt kê 1
Liệt kê 1 Sửa đổi tệp test-speaker.xhtml
<tr>
<td>type</td>
<td>_age_id</td>
<td>1</td>
</tr>
thành
<tr>
<td>type</td>
<td>_age_id</td>
<td>26</td>
</tr>
Lỗi này sẽ được sửa chữa trong một bản phát hành sau này của Spring Roo
Để chạy các trường hợp kiểm tra Selen, chúng ta cần khởi động máy chủ Tomcat Bạn có thể khởi động nó bằng cách sử dụng lệnh Maven là mvn tomcat:run Theo mặc định, tất cả các ứng dụng web được tạo ra bằng cách sử dụng Roo đều có các trình cắm thêm Maven cho các máy chủ web Tomcat và Jetty Để chạy selenium test, hãy thực hiện lệnh Maven mvn
selenium:selenese
Lệnh này sẽ khởi động một trình duyệt Firefox để chạy các trường hợp kiểm tra Selen Trong quá trình thực hiện các bài kiểm tra này, bạn sẽ thấy một hình ảnh tương tự như Hình 1
Trang 3Hình 1 Các bài kiểm tra Selen
Hiện nay, bất cứ ai cũng có thể truy cập ứng dụng của chúng ta và thực hiện tạo, cập nhật và xóa Speaker và Talk Trong một ứng dụng thời gian thực, có vấn đề bảo mật đối với những người có thể thực hiện hoạt động như vậy
Về đầu trang
Bảo mật ứng dụng web
Roo sử dụng Spring Security (Bảo mật Spring) để bổ sung bảo mật vào ứng dụng của bạn trong một dòng Spring Security là một xác thực tùy chỉnh rất cao và mạnh mẽ và là một khung công tác kiểm soát truy cập Nó là tiêu chuẩn trên thực tế để bảo mật các ứng dụng dựa trên Spring
Bổ sung Spring Security
Để thêm Spring Security, hãy gõ lệnh sau: security setup (thiết lập bảo mật)
Lệnh này sẽ thêm tất cả các tệp JAR của Spring Security cần thiết và sẽ thiết lập bảo mật cơ bản cho ứng dụng của bạn Lệnh này cũng tạo ra các tệp khác, nhưng có một tệp quan trọng là tệp
Trang 4applicationContext security.xml, có tất cả các định nghĩa bean liên quan đến bảo mật Ngữ cảnh của tệp applicationContext-security.xml trông giống như nội dung trong Liệt kê 2 Tôi đã thay thế mật khẩu được băm nhỏ với các dấu chấm chấm để làm cho nó dễ đọc hơn
Liệt kê 2 Ngữ cảnh của applicationContext-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans \
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security \ http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<! HTTP security configurations >
<http auto-config="true" use-expressions="true">
<form-login login-processing-url="/resources/j_spring_security_check"
\
login-page="/login" authentication-failure-url="/login?login_error=t"/>
<logout logout-url="/resources/j_spring_security_logout"/>
<! Configure these elements to secure URIs in your application > <intercept-url pattern="/choices/**" access="hasRole('ROLE_ADMIN')"/> <intercept-url pattern="/member/**" access="isAuthenticated()" /> <intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/**" access="permitAll" />
</http>
<! Configure Authentication mechanism >
<authentication-manager alias="authenticationManager">
<! SHA-256 values can be produced using \
'echo -n your_desired_password | sha256sum' \
(using normal *nix environments) >
<authentication-provider>
<password-encoder hash="sha-256"/>
<user-service>
<user name="admin" password=" "
authorities="ROLE_ADMIN"/>
<user name="user" password=" "
authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Bảo mật được Roo cấu hình là tổng quát và không có tài liệu tham khảo nào cho ứng dụng của chúng ta Hãy nhớ rằng Roo trợ giúp về thiết lập hoặc cấu hình một ứng dụng để khởi đầu nhanh chóng, nhưng trách nhiệm của nhà phát triển là tùy chỉnh sản phẩm cuối cùng Trong trường hợp này, Roo đã chỉ cung cấp một khuôn mẫu cho Spring Security và trách nhiệm của chúng ta là tùy chỉnh nó theo nhu cầu của mình
Trang 5Tùy chỉnh Spring Security
Trong ứng dụng của chúng ta, bất kỳ ai cũng có thể tạo ra một Speaker, nhưng chỉ có một
Speaker có thể tạo ra một Talk Chúng ta cần sửa đổi tệp applicationContext-security.xml như dưới đây Liệt kê 3 chỉ cho thấy một phần của XML cần sửa đổi
Liệt kê 3 Sửa đổi tệp applicationContext-security.xml
<http auto-config="true" use-expressions="true">
<form-login login-processing-url="/resources/j_spring_security_check"
\
login-page="/login" authentication-failure-url="/login?login_error=t"/>
<logout logout-url="/resources/j_spring_security_logout"/>
<! Configure these elements to secure URIs in your application > <intercept-url pattern="/talks/**" access="hasRole('ROLE_USER')"/> <intercept-url pattern="/speakers/**" access="permitAll" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/**" access="permitAll" />
</http>
Tôi đã cập nhật intercept-url sao cho chỉ những người dùng có vai trò người dùng mới có thể tạo ra một Talk và tất cả người dùng được phép tự đăng ký là Speaker
Spring Security do Roo-tạo ra đã hiển thị ở trên sử dụng một trình cung cấp xác thực trong bộ nhớ được cấu hình trong thẻ <user-service> Kể từ khi ứng dụng của chúng ta quản lý các thực thể Speaker, chúng ta nên xây dựng một trình cung cấp xác thực tùy chỉnh, sử dụng dữ liệu Speaker Để xác thực, chúng ta sẽ sử dụng email Speaker làm tên người dùng và thêm một trường mật khẩu cho thực thể Speaker, mà chúng ta sẽ sử dụng làm một mật khẩu xác thực
Một lần nữa, tôi sử dụng trình vỏ Roo để thêm trường password (mật khẩu) cho thực thể
Speaker:
field string class ~.domain.Speaker fieldName password notNull
sizeMin 6 –sizeMax 10
Tôi cũng đã thêm ràng buộc là mật khẩu nên không rỗng và mật khẩu phải có chiều dài từ 6 đến
10 ký tự
Do chúng ta đang sử dụng email và mật khẩu làm các tham số xác thực, chúng ta muốn tìm một Speaker với một email và mật khẩu cụ thể Spring Roo cung cấp một phương tiện để tạo ra các finder (bộ dò tìm) cho các ứng dụng của bạn khi sử dụng lệnh finder add (thêm bộ dò tìm):
finder add finderName findSpeakersByEmailAndPasswordEquals class
~.domain.Speaker
Trang 6Bạn có thể tìm thấy tất cả các bộ dò tìm cho một thực thể bằng cách sử dụng lệnh finder list
(liệt kê bộ dò tìm) Lệnh finder add (thêm bộ dò tìm) viết mã bộ dò tìm trong tệp
Speaker_Roo_Finder.aj và viết một số tệp có liên quan đến khung nhìn Điều này cho phép bạn tìm kiếm những người nói-Speaker từ giao diện đồ họa (GUI)
Viết AuthenticationProvider tùy chỉnh
Chúng ta sẽ viết một trình cung cấp xác thực (Authentication provider) tùy chỉnh bằng cách mở rộng một lớp tên là AbstractUserDetailsAuthenticationProvider, làm việc với tên người dùng/mật khẩu giống như xác thực Các lớp mở rộng
AbstractUserDetailsAuthenticationProvider phải cung cấp công cụ cho hai phương thức trừu tượng của nó: additionalAuthenticationChecks và retrieveUser Trình cung cấp gọi phương thức retrieveUser để xác thực Speaker bằng cách sử dụng email và mật khẩu đã nhập vào Việc tra cứu cơ sở dữ liệu cho Speaker được thực hiện khi sử dụng bộ dò tìm do chúng ta đã tạo ra ở trên Nếu tìm thấy Speaker, thì GrantedAuthority ROLE_USER sẽ được gán cho
Speaker đó Phương thức này cuối cùng trả về một đối tượng UserDetails đã điền vào nếu đăng nhập thành công hay nếu không sẽ đưa ra một BadCredentialsException với thông báo phù hợp (xem Liệt kê 4)
Liệt kê 4 Xác thực tuỳ chỉnh
package com.dw.roo.conference.security;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NonUniqueResultException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.security.authentication.BadCredentialsException; import
org.springframework.security.authentication.UsernamePasswordAuthenticationTok en;
import org.springframework.security.authentication.\
dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.StringUtils;
import com.dw.roo.conference.domain.Speaker;
public class ConferenceAuthenticationProvider extends \
AbstractUserDetailsAuthenticationProvider {
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, \ UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
Trang 7// TODO Auto-generated method stub
}
@Override
protected UserDetails retrieveUser(String username,
UsernamePasswordAuthenticationToken \
authentication) throws AuthenticationException {
String password = (String) authentication.getCredentials();
if (!StringUtils.hasText(password)) {
throw new BadCredentialsException("Please enter password");
}
List<GrantedAuthority> authorities = new
ArrayList<GrantedAuthority>();
try {
Speaker speaker =
Speaker.findSpeakersByEmailAndPasswordEquals(username, \
password).getSingleResult();
authorities.add(new GrantedAuthorityImpl("ROLE_USER"));
} catch (EmptyResultDataAccessException e) {
throw new BadCredentialsException("Invalid username or
password");
} catch (EntityNotFoundException e) {
throw new BadCredentialsException("Invalid user");
} catch (NonUniqueResultException e) {
throw new BadCredentialsException("Non-unique user, contact
administrator");
}
return new User(username, password, true, // enabled
true, // account not expired
true, // credentials not expired
true, // account not locked
authorities);
}
}
Trong tệp applicationContext-security.xml, chúng ta phải định nghĩa bean
conferenceAuthenticationProvider (trình cung cấp xác thực hội nghị) và thay thế trình cung cấp xác thực trong bộ nhớ do Roo tạo ra bằng conferenceAuthenticationProvider của chúng
ta như trong Liệt kê 5
Liệt kê 5 conferenceAuthenticationProvider
<beans:bean name="conferenceAuthenticationProvider"
class="com.dw.roo.conference.security.ConferenceAuthenticationProvider">
</beans:bean>
<! Configure Authentication mechanism >
<authentication-manager alias="authenticationManager">
<authentication-provider ref="conferenceAuthenticationProvider"/>
</authentication-manager>
Trang 8Bây giờ nếu bạn khởi động máy chủ và cố gắng tạo ra một Talk, một màn hình đăng nhập sẽ mở
ra trước bạn, ở đó bạn phải nhập email và mật khẩu của Speaker mà bạn đã tạo ra Mục đích của việc xây dựng trình cung cấp xác thực tùy chỉnh là không phải để xây dựng một trình cung cấp xác thực lý tưởng mà để cho bạn thấy những gì Roo làm và những gì bạn phải tự làm
Về đầu trang
Thông báo email
Trong ứng dụng của chúng ta, các Speaker sẽ nhận được một email khi họ tạo ra Talk, vì vậy hãy thêm sự hỗ trợ email cho ứng dụng của chúng ta Chúng ta sẽ sử dụng Gmail làm máy chủ SMTP của mình để tập trung vào việc gửi email khi sử dụng Roo Việc thêm sự hỗ trợ cho một ứng dụng được thực hiện bằng lệnh sau:
email sender setup hostServer smtp.gmail.com username \
<Your email address> password <Your email password> port 587 protocol SMTP
Lệnh email sender (người gửi email) cài đặt một JavaMailSender (Người gửi email Java) của Spring trong dự án của bạn Bạn có thể thay đổi các đặc tính liên quan đến email trong tệp
email.properties
Sau khi đã tạo ra Talk, chúng ta cần gửi một email Để làm việc đó, chúng ta cần thêm một trường email trong TalkController (Bộ điều khiển cuộc thảo luận) Để thêm một trường email, hãy gõ:
field email template class ~.web.TalkController
Lệnh này sẽ thêm một khuôn mẫu MailSender và một phương thức sendMessage (Gửi thông báo) tới TalkController Bây giờ chúng ta cần khởi động phương thức sendMessage sau khi một Talk được lưu giữ lâu bền trong cơ sở dữ liệu Khi tất cả mã dùng cho TalkController tồn tại trong tệp TalkController_Roo_Controller.aj, cách dễ nhất để thực hiện nhiệm vụ này là tạo ra một phương thức encodeUrlPathSegment từ tệp aj cho lớp TalkController và thêm một cuộc gọi đến phương thức sendMessage sau dòng talk.persist(), như trong Liệt kê 6
Liệt kê 6 Tạo ra một phương thức encodeUrlPathSegment từ tệp aj cho lớp
TalkController
public class TalkController {
@Autowired
private transient MailSender mailTemplate;
public void sendMessage(String mailFrom, String subject, String
mailTo,
String message) { org.springframework.mail.SimpleMailMessage \
Trang 9simpleMailMessage = new org.springframework.mail.SimpleMailMessage();
simpleMailMessage.setFrom(mailFrom);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setTo(mailTo);
simpleMailMessage.setText(message);
mailTemplate.send(simpleMailMessage);
}
@RequestMapping(method = RequestMethod.POST)
public String create(@Valid Talk talk, BindingResult result, Model model,
HttpServletRequest request) {
if (result.hasErrors()) {
model.addAttribute("talk", talk);
return "talks/create";
} talk.persist();
sendMessage("spring.roo.playground@gmail.com", "Your talk is created",
talk.getSpeaker().getEmail(), \
"Congrats your talk is created");
return "redirect:/talks/"
+ encodeUrlPathSegment(talk.getId().toString(), request);
}
private String encodeUrlPathSegment(String pathSegment,
HttpServletRequest request) { String enc = request.getCharacterEncoding();
if (enc == null) {
enc = WebUtils.DEFAULT_CHARACTER_ENCODING;
} try {
pathSegment = UriUtils.encodePathSegment(pathSegment, enc);
} catch (UnsupportedEncodingException uee) { }
return pathSegment;
}
}
Sau đây, các Speaker sẽ nhận được một email trong tài khoản đã định của mình sau khi Talk được tạo ra
Về đầu trang
Hỗ trợ quốc tế
Khi chúng ta đang xây dựng một ứng dụng web dựa trên Internet, điều quan trọng là hỗ trợ các ngôn ngữ khác nhau sao cho những người dùng từ khu vực địa lý khác nhau có thể sử dụng ứng dụng của chúng ta Spring Roo bổ sung sự hỗ trợ quốc tế bằng lệnh web mvc install
language, cài đặt một ngôn ngữ mới trong ứng dụng của bạn Ví dụ, các lệnh cho ngôn ngữ Tây Ban Nha và Ý là:
Trang 10web mvc install language code es
web mvc install language code it
Roo hiện hỗ trợ sáu ngôn ngữ và bạn có thể viết một ngôn ngữ bổ sung cho những ngôn ngữ khác theo sự lựa chọn của bạn Bây giờ khi chạy ứng dụng này, 2 lá cờ (của Italy và Tây Ban Nha) được hiển thị, cùng với lá cờ Anh Nếu bạn nhấn chuột vào bất kỳ lá cờ nào trong các lá cờ
đó, bạn sẽ xem ứng dụng web theo ngôn ngữ tương ứng với lá cờ đó
Về đầu trang
Xã hội hóa ứng dụng web của bạn
Đây là một kỷ nguyên phương tiện truyền thông xã hội và các tính năng xã hội thường được thêm vào các ứng dụng hiện tại Để thêm đoạn video của các Talk thường rất có ý nghĩa Roo cung cấp sự hỗ trợ để nhúng đoạn video được tải lên YouTube, Vimeo, Viddler và Google Video, v.v Để nhúng một đoạn video, hãy sử dụng lệnh sau:
web mvc embed video provider VIMEO videoId 16069687
Nếu bạn khởi động máy chủ và khởi chạy ứng dụng của mình trong một trình duyệt, bạn sẽ có thể xem đoạn video đã nhúng nói trên Tương tự như vậy, bạn có thể thêm vào các đoạn video YouTube hoặc Viddler
Roo cũng cung cấp cho bạn một tùy chọn để nhúng các thông báo Twitter, các tài liệu, các ticker, các bản đồ, các bức ảnh và các luồng video trong ứng dụng của bạn Các lệnh khác nhau trong Liệt kê 7
Liệt kê 7 Các lệnh nhúng
web mvc embed document
web mvc embed finances
web mvc embed map
web mvc embed photos
web mvc embed stream video
web mvc embed twitter
web mvc embed video
Về đầu trang
Kỹ thuật đảo ngược cơ sở dữ liệu
Kỹ thuật đảo ngược cơ sở dữ liệu (DBRE) cho phép bạn tự xem xét một cơ sở dữ liệu hiện có và trưng nó ra như một ứng dụng Để hiển thị cách DBRE làm việc, tôi sẽ tạo ra một ứng dụng liên
hệ ngược từ một lược đồ liên hệ ngược hiện có Tôi sẽ sử dụng MySQL làm một cơ sở dữ liệu