HSF302Chưa đoKỳ 5Tự chọn Cập nhật 1 ngày trước

HSF302 - Làm việc với Spring Framework

HSF302 - Làm việc với Spring Framework là môn 3 tín chỉ bậc cử nhân của Đại học FPT, học sau PRJ301. Vấn đề môn giải quyết là dựng một ứng dụng Java nhiều tầng mà không phải tự tay khởi tạo từng lớp rồi nối chúng với nhau. Điểm xuất phát là một yêu cầu HTTP: DispatcherServlet nhận nó, tìm phương thức controller khớp đường dẫn, gắn tham số vào đối số rồi trả về một trang hoặc một đối tượng JSON. Đằng sau controller là các đối tượng do IoC container tạo ra và tiêm vào nhau, nên lớp dịch vụ chỉ khai báo mình cần gì chứ không tự dựng phụ thuộc. Dữ liệu xuống cơ sở dữ liệu qua ánh xạ đối tượng–quan hệ: một lớp @Entity ứng với một bảng, quan hệ một-nhiều hay nhiều-nhiều được khai báo bằng annotation, và việc nạp dữ liệu liên quan sớm hay muộn định ra bao nhiêu câu truy vấn thật sự chạy. Trên lớp ánh xạ ấy, repository chỉ cần một interface, còn tên phương thức như findByEmail đủ để sinh truy vấn. Cùng lối tách giao diện khỏi dữ liệu được dùng lại cho ứng dụng máy tính để bàn, nơi cửa sổ, Scene và các điều khiển được dựng bằng mã Java hoặc tệp FXML. Spring Boot gom các mảnh đó bằng cấu hình tự động và các gói khởi động, để một dự án chạy được chỉ với một lớp main và vài dòng thuộc tính. Các khái niệm cần nắm chắc gồm th:each, bean, ObservableList, JpaRepository, Scene, Dependency Injection, @RestController và persistence context. Học xong, người học lần theo được đường đi của một yêu cầu qua các tầng, tự thiết kế lớp thực thể cùng quan hệ giữa chúng, viết controller trả trang Thymeleaf hoặc dữ liệu REST, chọn đúng phạm vi cho bean, và dựng một ứng dụng thêm, sửa, xoá có giao diện bằng JavaFX.

179Câu hỏi
5Bộ đề
9Chủ đề

Câu hỏi của môn

84/179 câuCòn 95
AOnly for handling exceptions.
BOnly for mapping requests.
CFor cross cutting concerns like logging, authentication, and authorization.
DOnly for defining views.
Lời giải
Đáp án đúng: "For cross cutting concerns like logging, authentication, and authorization.". Interceptor trong Spring MVC là lớp hiện thực HandlerInterceptor, được DispatcherServlet gọi quanh việc xử lý của handler: preHandle trước controller, postHandle sau controller nhưng trước khi render view, và afterCompletion khi yêu cầu xong; nhờ vậy nó hợp cho các mối quan tâm cắt ngang (cross-cutting concerns) áp cho nhiều controller như ghi log, kiểm tra đăng nhập, phân quyền, đo thời gian. "Only for handling exceptions." sai vì xử lý ngoại lệ có @ExceptionHandler và @ControllerAdvice, interceptor chỉ được báo ngoại lệ trong afterCompletion. "Only for mapping requests." sai vì việc ánh xạ yêu cầu tới controller do HandlerMapping làm, interceptor chỉ được gắn vào kết quả ánh xạ đó. "Only for defining views." sai vì view do controller trả về và ViewResolver phân giải; postHandle có thể chỉnh ModelAndView nhưng đó không phải mục đích duy nhất, chữ Only làm phát biểu sai.
Mở trang câu hỏi này →
AController
BHandlerMapping
CDispatcherServlet
DViewResolver
Lời giải
Đáp án đúng: "DispatcherServlet". Spring MVC theo mẫu front controller (bộ điều khiển đứng trước): DispatcherServlet được đăng ký là servlet nhận mọi yêu cầu khớp mẫu URL của ứng dụng, rồi điều phối phần còn lại của vòng đời. "HandlerMapping" chỉ được DispatcherServlet hỏi sau khi yêu cầu đã tới, để tìm handler phù hợp với URL và phương thức HTTP. "Controller" chỉ được gọi gián tiếp qua HandlerAdapter khi handler đã được xác định, nên nhận yêu cầu ở khâu giữa chứ không phải đầu tiên. "ViewResolver" đứng gần cuối chuỗi, đổi tên view logic do controller trả về thành view thực tế để dựng phản hồi. Các Filter của Servlet container, như bộ lọc của Spring Security, có thể chạm yêu cầu trước DispatcherServlet, nhưng trong các thành phần của Spring MVC thì DispatcherServlet là cửa vào đầu tiên.
Mở trang câu hỏi này →
AHandlerMapping
BHandlerAdapter
CViewResolver
DModelAndView
Lời giải
Đáp án đúng: "HandlerMapping". Trong luồng xử lý của Spring MVC, DispatcherServlet nhận mọi yêu cầu rồi hỏi các HandlerMapping, ví dụ RequestMappingHandlerMapping đọc @RequestMapping và @GetMapping, để tìm phương thức controller khớp với URL và phương thức HTTP; kết quả là một handler cùng chuỗi interceptor. "HandlerAdapter" đứng ở bước sau: khi đã biết handler nào, adapter mới thực sự gọi nó, lo phần gắn tham số và xử lý giá trị trả về, chứ không phải nơi tìm handler. "ViewResolver" làm việc ở cuối luồng, đổi tên view logic như home thành một View cụ thể như template Thymeleaf. "ModelAndView" chỉ là đối tượng chứa dữ liệu model và tên view mà handler trả về, không ánh xạ yêu cầu nào.
Mở trang câu hỏi này →
AStackPane
BBorderPane
CHBox
DVBox
Lời giải
Đáp án đúng: "BorderPane". Yêu cầu chia cửa sổ thành top, bottom, center, left và right khớp đúng năm vùng của BorderPane: mỗi vùng giữ tối đa một nút, gán bằng setTop, setBottom, setLeft, setRight, setCenter; vùng trên và dưới kéo hết chiều ngang, vùng trái phải lấy theo chiều rộng ưa thích của nút, còn center giãn ra lấp phần còn lại khi cửa sổ đổi kích thước. "StackPane" chồng các nút con lên nhau tại cùng một vị trí, mặc định căn giữa, hợp với việc đặt chữ lên ảnh nền chứ không chia vùng. "HBox" chỉ xếp các nút theo một hàng ngang. "VBox" chỉ xếp các nút theo một cột dọc. Muốn có năm vùng bằng HBox hay VBox phải lồng nhiều layout, trong khi BorderPane làm sẵn việc đó.
Mở trang câu hỏi này →
69Spring Boot embedded servers include:4 lựa chọn
AApache Tomcat
BJetty
CUndertow
DAll of the above
Lời giải
Đáp án đúng: "All of the above". Trong các bản Spring Boot 2.x và 3.x, ứng dụng servlet được hỗ trợ sẵn ba web server nhúng (embedded server): thêm spring-boot-starter-web thì mặc định là Tomcat, và có thể loại Tomcat ra rồi thêm starter tương ứng để đổi sang Jetty hoặc Undertow; server chạy ngay trong tiến trình khi khởi động ứng dụng từ tệp jar, không cần cài server ngoài. "Apache Tomcat" đúng nhưng chỉ là lựa chọn mặc định, chọn riêng nó bỏ sót hai server kia. "Jetty" là server nhúng nhẹ của Eclipse, được hỗ trợ qua spring-boot-starter-jetty, nhưng cũng chỉ là một phần của danh sách. "Undertow" là server hiệu năng cao của Red Hat, hỗ trợ qua spring-boot-starter-undertow, cũng chưa đủ. Vì câu hỏi liệt kê các server nhúng nên chọn đáp án bao gồm cả ba.
Mở trang câu hỏi này →
ADatabase connectivity.
BWeb application development.
CSecurity configuration.
DMessaging.
Lời giải
Đáp án đúng: "Web application development.". spring-boot-starter-web là starter POM (gói phụ thuộc khởi đầu) gom sẵn Spring MVC, Jackson để chuyển đổi JSON và Tomcat nhúng, đủ để viết ứng dụng web và REST API chỉ với một phụ thuộc; auto-configuration sẽ tự dựng DispatcherServlet và máy chủ nhúng khi thấy các thư viện này trên classpath. "Database connectivity." sai vì kết nối cơ sở dữ liệu đến từ spring-boot-starter-data-jpa hoặc spring-boot-starter-jdbc. "Security configuration." sai vì bảo mật có starter riêng là spring-boot-starter-security. "Messaging." sai vì nhắn tin dùng các starter như spring-boot-starter-amqp cho RabbitMQ hay thư viện spring-kafka, không nằm trong starter web.
Mở trang câu hỏi này →
ASpring Initializr
BMaven Archetype
CGradle Plugin
DJDK installer
Lời giải
Đáp án đúng: "Spring Initializr". Spring Initializr là dịch vụ tạo khung dự án Spring Boot, dùng qua trang start.spring.io hoặc tích hợp sẵn trong IntelliJ IDEA, VS Code, Spring Tool Suite: chỉ cần chọn Maven hay Gradle, phiên bản Java, Spring Boot và các starter như Web, Data JPA, Thymeleaf là nhận ngay một dự án có sẵn lớp main, pom.xml hoặc build.gradle và application.properties. "Maven Archetype" là cơ chế mẫu dự án chung của Maven, dùng được cho mọi loại dự án Java nhưng không chọn starter Spring Boot nhanh như vậy. "Gradle Plugin" ở đây là plugin Spring Boot cho Gradle, dùng để chạy và đóng gói jar chạy được, chứ không sinh dự án mới. "JDK installer" chỉ cài bộ công cụ phát triển Java, là điều kiện cần nhưng không tạo dự án.
Mở trang câu hỏi này →
A@RestController
B@Service
C@Entity
D@Bean
Lời giải
Đáp án đúng: "@RestController". @RestController là annotation tổng hợp gồm @Controller và @ResponseBody: lớp vẫn là handler web được Spring MVC quét, nhưng giá trị trả về của mọi phương thức được ghi thẳng vào thân phản hồi HTTP thông qua HttpMessageConverter, thường chuyển đối tượng Java thành JSON bằng Jackson, thay vì bị hiểu là tên view. Đây là cách viết REST API chuẩn trong Spring. "@Service" đánh dấu bean tầng nghiệp vụ, không nhận yêu cầu HTTP. "@Entity" là annotation JPA đánh dấu lớp ánh xạ tới bảng cơ sở dữ liệu. "@Bean" đặt trên phương thức trong lớp @Configuration để khai báo rằng đối tượng trả về được đăng ký làm bean, không liên quan tới việc xử lý yêu cầu REST.
Mở trang câu hỏi này →
Ath:if
Bth:each
Cth:text
Dth:href
Lời giải
Đáp án đúng: "th:each". Thuộc tính th:each của Thymeleaf lặp qua một tập hợp như List, mảng hay Map và lặp lại phần tử HTML chứa nó cho mỗi phần tử, ví dụ đặt th:each với biểu thức s : ${students} trên thẻ tr sẽ sinh một dòng bảng cho mỗi sinh viên, kèm biến trạng thái cho chỉ số và số đếm. "th:if" chỉ hiển thị phần tử khi biểu thức đúng, là điều kiện chứ không phải vòng lặp. "th:text" thay nội dung văn bản của phần tử bằng giá trị biểu thức, có thoát ký tự HTML. "th:href" tính giá trị thuộc tính href, thường kèm cú pháp liên kết @{...} để dựng URL đúng context path. Muốn hiển thị danh sách thì dùng th:each bao ngoài, rồi th:text bên trong cho từng giá trị.
Mở trang câu hỏi này →
AXML templates
BText templates
CJSON templates
DBinary templates
Lời giải
Đáp án đúng gồm hai ý: "XML templates" và "Text templates". Thymeleaf xử lý sáu chế độ template (template mode): HTML, XML, TEXT, JAVASCRIPT, CSS và RAW; trong đó XML là chế độ đánh dấu (markup) dành cho tài liệu XML hợp lệ, còn TEXT là chế độ văn bản thuần dùng cú pháp biểu thức nội tuyến để sinh email chữ, tệp cấu hình hay văn bản bất kỳ không có thẻ. "JSON templates" sai vì Thymeleaf không có chế độ JSON riêng; muốn sinh JSON thì dùng chế độ TEXT hoặc JAVASCRIPT, còn trong ứng dụng Spring thường để Jackson tuần tự hoá đối tượng. "Binary templates" sai vì Thymeleaf là template engine cho dữ liệu dạng văn bản, không xử lý tệp nhị phân như ảnh hay PDF.
Mở trang câu hỏi này →
Đề bài
<a th:href="______">Home</a>
A${/home}
B#{/home}
C@{/home}
D~{/home}
Lời giải
Đáp án đúng: "@{/home}". Trong cú pháp biểu thức chuẩn của Thymeleaf, @{...} là biểu thức URL liên kết (link URL expression): với đường dẫn bắt đầu bằng dấu gạch chéo, Thymeleaf tự thêm context path của ứng dụng, cho phép truyền tham số như @{/home(id=${id})} và mã hoá URL, nên th:href="@{/home}" sinh ra liên kết đúng dù ứng dụng chạy ở đường dẫn gốc nào. "${/home}" là biểu thức biến, dùng để đọc thuộc tính trong model, còn /home không phải tên biến hợp lệ. "#{/home}" là biểu thức thông điệp, dùng để tra khoá trong tệp messages cho đa ngôn ngữ. "~{/home}" là biểu thức fragment, dùng với th:insert hoặc th:replace để chèn một mảnh template, không tạo đường dẫn liên kết.
Mở trang câu hỏi này →
76Thymeleaf integrates well with:4 lựa chọn
AReact.js
BAngular.js
CSpring MVC.
DNode.js
Lời giải
Đáp án đúng: "Spring MVC.". Thymeleaf là template engine chạy phía máy chủ trên Java và có module tích hợp riêng thymeleaf-spring: ThymeleafViewResolver cắm vào luồng của DispatcherServlet, template đọc được dữ liệu trong Model, dùng biểu thức Spring EL, liên kết form với đối tượng qua th:object và th:field, hiển thị lỗi validation; Spring Boot còn tự cấu hình mọi thứ khi có spring-boot-starter-thymeleaf. "React.js" là thư viện JavaScript dựng giao diện phía trình duyệt, tự render bằng JavaScript nên không dùng template máy chủ của Java. "Angular.js" cũng là framework phía client có cú pháp template riêng chạy trong trình duyệt. "Node.js" là môi trường chạy JavaScript phía máy chủ, dùng các engine như EJS hay Pug, còn Thymeleaf là thư viện Java nên không chạy trên môi trường đó.
Mở trang câu hỏi này →
77Thymeleaf can be used to process:4 lựa chọn
AOnly HTML files.
BHTML, XML, JavaScript, CSS, and plain text.
COnly server-side Java code.
DOnly database queries.
Lời giải
Đáp án đúng: "HTML, XML, JavaScript, CSS, and plain text.". Thymeleaf là template engine (bộ máy mẫu) phía server cho Java, hỗ trợ sáu chế độ mẫu: HTML và XML là chế độ đánh dấu, TEXT, JAVASCRIPT và CSS là chế độ văn bản, cùng RAW để xuất nguyên văn; nhờ vậy nó sinh được trang web, tệp XML, đoạn script hay nội dung email dạng văn bản thuần. "Only HTML files." sai vì HTML chỉ là chế độ thường gặp nhất trong Spring MVC chứ không phải duy nhất. "Only server-side Java code." sai vì Thymeleaf không xử lý mã Java, nó xử lý mẫu và chỉ đọc dữ liệu từ model qua biểu thức. "Only database queries." sai vì truy vấn cơ sở dữ liệu là việc của JPA hay JDBC, Thymeleaf không truy cập cơ sở dữ liệu.
Mở trang câu hỏi này →
A@ManyToOne
B@OneToOne
C@OneToMany
D@ManyToMany
Lời giải
Đáp án đúng: "@OneToMany". @OneToMany đặt trên một trường kiểu tập hợp, ví dụ danh sách các Order trong entity Customer, cho biết một khách hàng có nhiều đơn hàng; nó thường đi kèm mappedBy trỏ tới trường ở phía nhiều để quan hệ hai chiều dùng chung một cột khoá ngoại. "@ManyToOne" mô tả chiều ngược lại, đặt ở phía nhiều, chẳng hạn trường customer trong Order, nơi giữ cột khoá ngoại; nó là nửa kia của quan hệ chứ không khai báo một-nhiều nhìn từ phía một. "@OneToOne" dành cho quan hệ một-một như User và Profile, mỗi bên chỉ có tối đa một đối tượng tương ứng. "@ManyToMany" dành cho quan hệ nhiều-nhiều như Student và Course, cần một bảng nối ở giữa.
Mở trang câu hỏi này →
ASpring MVC
BHibernate
CJavaFX
DSwing
Lời giải
Đáp án đúng: "Hibernate". Hibernate là framework ORM (Object-Relational Mapping, ánh xạ đối tượng sang quan hệ) phổ biến nhất của Java: nó ánh xạ lớp Java sang bảng, tự sinh SQL cho thao tác thêm, sửa, xoá, truy vấn, quản lý persistence context và cache, đồng thời là nhà cung cấp JPA mặc định mà Spring Boot dùng khi thêm starter Data JPA. "Spring MVC" là framework web theo mẫu Model-View-Controller, xử lý yêu cầu HTTP qua DispatcherServlet chứ không ánh xạ đối tượng sang bảng. "JavaFX" là bộ công cụ xây dựng giao diện ứng dụng desktop. "Swing" cũng là thư viện giao diện desktop, ra đời trước JavaFX, không liên quan tới truy cập dữ liệu.
Mở trang câu hỏi này →
A@OneToMany
B@ManyToOne
C@OneToOne
D@Autowired
Lời giải
Đáp án đúng: "@Autowired". Câu hỏi tìm annotation KHÔNG thuộc nhóm quan hệ của JPA. @Autowired là annotation của Spring dùng để tiêm phụ thuộc, yêu cầu container tìm bean phù hợp theo kiểu rồi gán vào trường, setter hay constructor; nó không mô tả quan hệ giữa các entity. "@OneToMany" là annotation quan hệ chuẩn trong jakarta.persistence, đặt ở phía một để giữ tập hợp nhiều entity con, ví dụ một Department có nhiều Employee, nên nó thuộc nhóm và không được chọn. "@ManyToOne" cũng là quan hệ chuẩn, đặt ở phía nhiều và thường kèm @JoinColumn chỉ cột khoá ngoại. "@OneToOne" là quan hệ chuẩn một một, như User với hồ sơ Profile. Cùng với @ManyToMany, chúng tạo thành bốn annotation quan hệ của đặc tả JPA.
Mở trang câu hỏi này →
ATo define a single named query
BTo define multiple named queries
CTo define a primary key
DTo define a foreign key
Lời giải
Đáp án đúng: "To define multiple named queries". Named query là câu JPQL được đặt tên, khai báo tĩnh trên lớp thực thể bằng @NamedQuery với name và query, rồi gọi qua em.createNamedQuery. Ở các bản JPA trước 2.2, @NamedQuery không lặp lại được trên cùng một lớp, nên @NamedQueries làm annotation chứa, nhận một mảng nhiều @NamedQuery; từ JPA 2.2 có thể lặp trực tiếp, nhưng @NamedQueries vẫn là cách gom nhiều truy vấn đặt tên. "To define a single named query" là việc của chính @NamedQuery. "To define a primary key" là việc của @Id hoặc @EmbeddedId. "To define a foreign key" thuộc về @JoinColumn trên quan hệ, hoặc @ForeignKey để đặt tên ràng buộc, không liên quan truy vấn đặt tên.
Mở trang câu hỏi này →
Đề bài
private Long id;
AIt creates a foreign key for the entity
BIt marks the field as a version column
CIt marks the field as the primary key with auto-increment strategy
DIt disables the persistence of the field
Lời giải
Đáp án đúng: "It marks the field as the primary key with auto-increment strategy". Lần theo mã: @Id đánh dấu trường id là khoá chính của entity, còn @GeneratedValue(strategy = GenerationType.IDENTITY) báo JPA không tự cấp giá trị mà để cột identity hay auto-increment của cơ sở dữ liệu sinh khi INSERT, sau đó provider đọc lại khoá vừa sinh và gán vào trường id kiểu Long. "It creates a foreign key for the entity" sai vì khoá ngoại khai báo bằng @ManyToOne hoặc @OneToOne kèm @JoinColumn, không phải @Id. "It marks the field as a version column" sai vì cột phiên bản cho khoá lạc quan (optimistic locking) dùng @Version. "It disables the persistence of the field" sai vì muốn một trường không được lưu xuống bảng thì dùng @Transient; ở đây trường id lại là trường quan trọng nhất được lưu.
Mở trang câu hỏi này →
Asave()
Binsert()
Cpersist()
Dstore()
Lời giải
Đáp án đúng: "persist()". Trong JPA, EntityManager.persist(entity) đưa một thực thể mới từ trạng thái transient (tạm thời) vào persistence context để nó thành managed; câu lệnh INSERT thực sự được gửi khi flush hoặc khi transaction commit. EntityManager còn có merge, remove, find, nhưng thêm mới là persist. "save()" là chỗ dễ nhầm: đó là phương thức của repository trong Spring Data JPA, và bên trong SimpleJpaRepository.save lại gọi persist hoặc merge tuỳ thực thể mới hay cũ, nó cũng có trong Session của Hibernate, nhưng không thuộc EntityManager. "insert()" không có trong API EntityManager, INSERT là câu SQL do JPA tự sinh. "store()" cũng không phải phương thức của EntityManager.
Mở trang câu hỏi này →
Aem.persist(entity);
Bem.remove(entity);
Cem.find(Entity.class, id);
Dem.merge(entity);
Lời giải

Đáp án đúng: "em.merge(entity); ". Cập nhật một entity trong ứng dụng JavaFX thường diễn ra khi đối tượng đã được nạp từ trước, hiển thị trên form, người dùng sửa rồi bấm lưu; lúc đó entity đã ở trạng thái detached (tách khỏi persistence context) vì EntityManager cũ đã đóng, nên phải gọi merge trong một giao dịch: JPA chép trạng thái của nó vào bản managed có cùng khoá chính và khi commit sẽ sinh câu UPDATE. Chú ý merge trả về bản managed, còn đối tượng truyền vào vẫn detached. "em.persist(entity); " dùng cho entity mới, sinh INSERT và báo lỗi khi gặp entity detached. "em.remove(entity); " xoá entity, sinh DELETE. "em.find(Entity.class, id);"chỉ nạp entity theo khoá chính, là bước đọc chứ không ghi thay đổi; tuy entity vừa find rồi sửa trong cùng giao dịch cũng được cập nhật nhờ dirty checking, bản thân lệnh đó không thực hiện việc cập nhật.

Mở trang câu hỏi này →