Service Builder
Service layer : Controller와 Persistence layer 사이의 버퍼 역할
Service.xml을 통해 Model, Service, Persistence layer를 자동으로 생성해낸다.
Loose coupling을 지원함으로써, Persistence layer가 바뀌어도 Model과 Service layer에서는 큰 변화없이 적용이 가능하다.
Guestbook example에서 service.xml에 설정한 것
Entities에 Guestbook, Entry 생성 -> Entities에 설정한 값은 Table 역할
Guestbook, Entry에 Columns 생성
Finder 설정 -> 설정한 attribute 값으로 찾을 수 있게 하는 역할 (이 예제에서는 Guestbook을 Group ID로 찾게 함 \/ Entry는 Group ID와 Guestbook ID로 찾게 함)
Exception 설정 -> 사용자가 어떤 field를 꼭 입력하게끔 하는 역할 aka Required
Finder 부가 설명 : 추후에 G_N, G_S라는 이름으로 finder를 더 만들고 column으로 G_N은 (groupId, Name), G_S는 (groupId, status)를 추가한다. 이들은 build service 후에 -LocalServiceImpl.java에서 method 구현시 사용하게 된다. ex, guestbookPersistence.findByGroupID, guestbookPersistence.findByG_S, guestbookPersistence.findByG_N
Service.xml의 Build services 후 구현 내용
Build Services를 하면 Model, Service, Persistence에 대한 패키지가 자동으로 생성된다.
Model : GuestbookBaseImpl (Abstract class) -> GuestbookImpl (Customize 할 수 있음) \/ Entry도 동일
Service layer의 구현 -> -service.impl package에 코드 채워넣기 (추후 이 기능들을 Controller에서 사용)
-LocalServiceImpl.java는 Local service용, -ServiceImpl.java는 Remote service용 클래스
Controller는 -LocalServiceImpl.java로부터 method를 call 한다. (Direct call이 아닌 -Util class를 이용)
GuestbookLocalServiceImpl.java 파일에 필요한 기능들을 구현하여 service layer로서의 기능 제공
※ guestbookPersistence에는 service.xml의 finder에서 설정한 함수들이 있는 듯하다. entryPersistence도 마찬가지. (ex, findByGroupId, findByG_G)
GuestbookLocalServiceImpl.java와 EntryLocalServiceImpl.java에 구현한 내용들** (Service layer의 구현)**
getGuestbooks method : -Persistence class에서 findByGroupId method (groupId attribute를 이용해서 검색)를 이용하여 guestbook 객체들을 리턴.
validate method : 앞서 service.xml에 설정했던 Exception을 사용.
addGuestbook method : userId, name, serviceContext를 parameter로 받음. ※ Service Context : 유저의 browser와 Liferay Portal 사이의 현재 세션의 정보를 접근하기 위한 Object. 현재 유저의 ID, 현재 page, site, portal instance 의 ID등의 정보를 갖고 있다. (여기선 GroupID를 받아오는 데 사용, GroupID 정의 : The ID of the site the application is on)
// addGuestbook
long groupId = serviceContext.getScopeGroupId(); // serviceContext로부터 groupId (해당 포틀릿이 있는 사이트의 ID)를 받아옴
User user = userPersistence.findByPrimaryKey(userId); // persistence layer의 method인 findByPrimaryKey 사용해서 User정보 받아옴
Date now = new Date();
validate(name);
// 해당 사용자의 Guestbook을 추가하기 위해 Guestbook Table의 column 내용들을 채운다.
long guestbookId = counterLocalService.increment(); // primary key 설정
Guestbook guestbook = guestbookPersistence.create(guestbookId); // 해당 primary key로 guestbook을 하나 생성
// 값 추가하는 다양한 방법들을 알아두자 (serviceContext에서 가져오는 값들, user에서 가져오는 값들)
guestbook.setUuid(serviceContext.getUuid()); // 필요한 값들 추가
guestbook.setUserId(userId);
guestbook.setGroupId(groupId);
guestbook.setCompanyId(user.getCompanyId());
guestbook.setUserName(user.getFullName());
guestbook.setCreateDate(serviceContext.getCreateDate(now));
guestbook.setModifiedDate(serviceContext.getModifiedDate(now));
guestbook.setName(name);
guestbook.setExpandoBridgeAttributes(serviceContext);
guestbookPersistence.update(guestbook);
return guestbook;
getEntries method : -Persistence class에서 findByG_G method를 이용해서 entry 객체들을 리턴
addEntries method
Controller의 구현
- 이에 service layer에 구현했던 method들을 이용하여 controller로서의 기능을 제공. (단, -LocalServiceImpl.java의 method call이 아니라 -LocalServiceUtil class의 method를 call하여 구현한다.)
GuestbookPorlet.java에 구현한 내용들 **(Controller의 구현)**
addGuestbook method : serviceContext로부터 현재 User의 ID를 받아오고, JSP로부터 name을 받아와서 GuestbookLocalServiceUtil class의 addGuestbook(userID, name, serviceContext)를 실행한다.
try-catch block에서는 service layer에서 구현했던 validate method가 적용이 된다.
※ serviceContext에 있는 method 목록 getScopeGroup, getScopeGroupId, getUserId, getUuid, getGroupPermission, getGuestPermission 등등
addEntry method (addGuestbook과 비슷해서 생략)
render method : serviceContext로부터 현재 Guestbook에 대한 정보(Group ID)를 받아온다. 그리고 JSP로부터 guestbook ID를 받아온다. Group ID를 통해 GuestbookLocalServiceUtil class에서 getGuestbooks method를 호출하여 해당하는 guestbook들을 받아온다.
- 해당하는 guestbook이 하나도 없다면, "Main" 이라는 이름의 Guestbook을 생성한다.
jsp에 구현한 내용들** (View layer의 구현)**
init.jsp (import 통합관리) 파일 작성
view.jsp에서 Navigation tab, Add guestbook & entry button 구현
Search Container 구현
<liferay-ui:search-container
total="<%=EntryLocalServiceUtil.getEntriesCount(scopeGroupId,
guestbookId)%>"
>
<liferay-ui:search-container-results
results="<%=EntryLocalServiceUtil.getEntries(scopeGroupId,
guestbookId, searchContainer.getStart(),
searchContainer.getEnd())%>" />
<liferay-ui:search-container-row
className="com.liferay.docs.guestbook.model.Entry" modelVar="entry">
<liferay-ui:search-container-column-text property="message" />
<liferay-ui:search-container-column-text property="name" />
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
Search Container 자세한 설명
total 파라미터 : guestbook entry의 total number를 call
results 파라미터 : entry를 retrieve
row는className 파라미터로는 Entry, modelVar는 entry로 설정
column-text는 보여줄 column들을 설정 (message, name)
edit_entry.jsp, edit_guestbook.jsp 구현
<liferay-ui:search-container total="<%=DatasetLocalServiceUtil.getDatasetsCount()%>">
<liferay-ui:search-container-results results="<%=DatasetLocalServiceUtil.getDatasets(scopeGroupId,
searchContainer.getStart(), searchContainer.getEnd())%>" />
<liferay-ui:search-container-row className="com.liferay.docs.datasubmit.model.Dataset" modelVar="ds">
<liferay-ui:search-container-column-text name="DataType" value="<%=ds.getDataType() %>"/>
<liferay-ui:search-container-column-text name="Abstract" value="<%=ds.getAbstract() %>" />
<liferay-ui:search-container-column-text name="Description" value="<%=ds.getDescription() %>"/>
<liferay-ui:search-container-column-text name="Keyword" value="<%=ds.getKeyword() %>"/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>