Slim3�́AGoogle App Engine for Java�iGAE/J�j�p��MVC�t���[�����[�N�B
�O���[�o���g�����U�N�V�����������鑼�ABigtable�ւ̃A�N�Z�X��JDO/JPA��葬���炵���B
|
|
|
Slim3��Eclipse����B
���AEclipse�̃v���O�C���̂悤�Ȍ`���ł͂Ȃ��̂ŁA�g���j���[����V�K�v���W�F�N�g��Slim3�̃v���W�F�N�g���쐬����h�̂ł͂Ȃ��B
Slim3�̃u�����N�v���W�F�N�g���_�E�����[�h���Ă��āAEclipse�ɃC���|�[�g����B
�Q�l�F Slim3 ���{��T�C�g(�����)���u�����N�v���W�F�N�g�̓���
�v�f�� | �ҏW���e | |
---|---|---|
context-param |
<param-name>slim3.rootPackage</param-name> |
param-value�̒l���������g�p����p�b�P�[�W���ɂ���B �Ⴆ�ujp.hishidama.gae.slim3.ex1�v |
servlet |
<servlet-name>GWTServiceServlet</servlet-name> |
�R�����g�A�E�g���O���B |
�v���W�F�N�g�����s�i�u���s�v���uWeb�A�v���P�[�V�����v�j����ƁA�uDevelopment Mode�v�Ƃ����r���[���J���B
�����ɕ\������Ă���uhttp://127.0.0.1:8888/index.html?gwt.codesvr=127.0.0.1:9997
�v���u���E�U�[�ŊJ���ƁA�ŏ��ɁuGoogle
Web Toolkit Developer Plugin�v�̃C���X�g�[�����v�������B
GwtDevPluginSetup.exe���_�E�����[�h���Ď��s���ăC���X�g�[������B
�ēx�uhttp://127.0.0.1:8888/index.html?gwt.codesvr=127.0.0.1:9997
�v���J���ƁA�u���E�U�[��͐^�����̉�ʂ��\������邾���B�iGwtDevPlugin��ActiveX�̎��s�͋����Ă����j
Eclipse�́uDevelopment Mode�v�r���[�ɂ́uModule main has been loaded�v�Ƃ������b�Z�[�W���\�������B
���̎��_�Łuhttp://127.0.0.1:8888/index.html
�v�ɃA�N�Z�X����ƁA�uWeb�y�[�W����̃��b�Z�[�W�v�Ƃ����^�C�g���̃G���[�_�C�A���O���\�������B���͂́uGWT
module 'main' may need to be (re)compiled�v�B
�������ꂽindex.html�������JavaScript�����s���Ă��邾���̂悤�Ȃ̂ŁA�p�����[�^�[�����ŊJ���z��ł͂Ȃ��̂��낤�B
���[�U�[�����̉�ʁi�\����������͂��Ă�������肷��j���쐬���Ă݂�B
�i���������̕��@�́ASlim3�Ƃ�������GAE/J�̎������@�̂悤�ȋC������B
Slim3��MVC�A�܂�Controller��JSP���g�����@�̏ꍇ�A���̃��[�U�[�C���^�[�t�F�[�X�͕s�v�����H�j
�Q�l�F Slim3 ���{��T�C�g(�����)�����[�U�[�C���^�[�t�F�C�X�̍쐬
package jp.hishidama.gae.slim3.ex1.client; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; public class Main extends Composite { private static MainUiBinder uiBinder = GWT.create(MainUiBinder.class); interface MainUiBinder extends UiBinder<Widget, Main> { } @UiField Button button; public Main(String firstName) { initWidget(uiBinder.createAndBindUi(this)); button.setText(firstName); } @UiHandler("button") void onClick(ClickEvent e) { Window.alert("Hello!"); } }
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"> <ui:style> .important { font-weight: bold; } </ui:style> <g:HTMLPanel> Hello, <g:Button styleName="{style.important}" ui:field="button" /> </g:HTMLPanel> </ui:UiBinder>
Slim3�����[�U�[�C���^�[�t�F�C�X�̍쐬�y�[�W�ɏ�����Ă�����̂Ƃ͓��e���قȂ��Ă��邪�A�����ƃo�[�W�����Ⴂ�̏��ׂ��낤�B
�����āAMainEntryPoint.java���A��������Main�N���X���Ăяo���悤�C������B
package jp.hishidama.gae.slim3.ex1.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.ui.RootPanel; public class MainEntryPoint implements EntryPoint { public void onModuleLoad() { RootPanel.get().add(new Main("hishidama")); } }
���Ȃ݂ɁuonModuleLoad()�v�̓C���^�[�t�F�[�X�Ő錾����Ă��郁�\�b�h�̎��������A@Override�A�m�e�[�V�����͕t���Ȃ��B
�Ȃ��Ȃ�ASlim3�̃u�����N�v���W�F�N�g��JDK1.5�����ɂȂ��Ă��邩��B
�u���E�U�[�Łuhttp://127.0.0.1:8888/index.html?gwt.codesvr=127.0.0.1:9997
�v���J���i���邢�͊��ɊJ���Ă����̂�������X�V/�����[�h����j�ƁAMain.ui.xml�̓��e��HTML�ɕϊ�����ĕ\�������B
���̃{�^���������ƁA�uHello!�v�Ƃ����_�C�A���O���\�������B
Main.java��Main.ui.xml�͂��݂��ɖ��ڂȊW�ɂ���B
Main.java |
public class Main extends Composite { �` @UiField Button button; // �R���X�g���N�^�[ public Main(String firstName) { initWidget(uiBinder.createAndBindUi(this)); button.setText(firstName); } @UiHandler("button") void onClick(ClickEvent e) { Window.alert("Hello!"); } } |
---|---|
Main.ui.xml |
<g:HTMLPanel> Hello, <g:Button styleName="{style.important}" ui:field="button" /> </g:HTMLPanel> |
Main�N���X�̒���button�Ƃ������O�̃t�B�[���h�i�����o�[�ϐ��j������B
Main()�R���X�g���N�^�[�̒���button.setText()���s�����Ƃɂ��A�{�^���̃e�L�X�g���Z�b�g���Ă���B���ꂪ��ʕ\�����ɕ\������Ă���B
Main.ui.xml�́ug:Button�v�Ƃ����v�f���A�{�^�������Ă���B
�����́uui:field�v�Ƃ��������̒l�́AMain.java�́u@UiField�v�A�m�e�[�V������t�����t�B�[���h�̕ϐ����ƈ�v���Ă���K�v������B
�܂��AMain#onClick()�́u@UiHandler�v�A�m�e�[�V�����̒l���AMain.ui.xml��ui:field�ŕt����ꂽ���O�ƈ�v���Ă���K�v������B
�Ⴆ�ubutton�v�Ƃ������O��ʂ̖��O�ɕς�����������A��L��4�ӏ��S�Ă����O�ɕς���K�v������B
Main�N���X�̃t�B�[���h�������ς���ƁA�u���̖��O��Main.ui.xml�ɖ����v�Ƃ����|�̃G���[��Eclipse��ɕ\�������B
������Main.ui.xml��ui:field�̒l��ς���ƁAMain#onClick()�ɕt���Ă���u@UiHandler�v�A�m�e�[�V�����̒l���uMain.ui.xml�ɖ����v�Ƃ����G���[����������B
�A������ӏ��̃G���[�`�F�b�N��������Ƃ���Ă���̂͂������B
Slim3�ł́A��ʑJ�ڂ�Controller�ɂ���Đ��䂷��B
�u�����N�v���W�F�N�g�ɓ����Ă���build.xml�ɂ���āAController�N���X��jsp�t�@�C���̐��`�����邱�Ƃ��o����B
build.xml�́ugen-controller�v�����s����ƁA�p�X�i���s����URL�̈ꕔ�j����͂���_�C�A���O���J���B
�����Ƀp�X����͂���ƁA����ɊY������Controller�N���X��jsp�t�@�C�������������B
Controller�N���X�́A����JSP��\������ׂɎg�p�����iJSP�̕\���O�iJSP�ւ̃t�H���[�h�O�j�ɌĂ��j�B
�p�X | ���������t�@�C�� | �A�N�Z�X����URL | |
---|---|---|---|
���[�J���i�e�X�g�j | �C���^�[�l�b�g�i�{�ԁj | ||
/ | war/index.jsp src/�`/server/controller/IndexController.java test/�`/server/controller/IndexControllerTest.java |
http://localhost:8888/ |
http://aid.appspot.com/ |
/aaa/ | war/aaa/index.jsp src/�`/server/controller/aaa/IndexController.java test/�`/server/controller/aaa/IndexControllerTest.java |
http://localhost:8888/aaa/ |
http://aid.appspot.com/aaa/ |
/aaa/bbb | war/aaa/bbb.jsp src/�`/server/controller/aaa/BbbController.java test/�`/server/controller/aaa/BbbControllerTest.java |
http://localhost:8888/aaa/ bbb |
http://aid.appspot.com/aaa/ bbb |
package jp.hishidama.gae.slim3.ex1.server.controller;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
public class IndexController extends Controller {
@Override
public Navigation run() throws Exception {
return forward("index.jsp"); ��index.jsp�փt�H���[�h����悤�L�q����Ă���
}
}
����index.jsp�ɃA�N�Z�X����ɂ́A�uhttp://localhost:8888/�v���u���E�U�[�ŊJ���B
jsp�ɂ͒��ڃA�N�Z�X�ł��Ȃ��悤�ɂȂ��Ă���̂ŁA�uhttp://localhost:8888/index.jsp�v��403 FORBIDDEN�ɂȂ�B
���������[�U�[�C���^�[�t�F�[�X�̍쐬�iMainEntryPoint�̍쐬�j�ɂ����index.html��p�ӂ��Ă����ꍇ�A������̕����D�悳��A��������index.jsp�͎g�p����Ȃ��B
���������āAindex.html���폜���Ă����K�v������B�i���邢�̓��l�[�����Ă����j
Main.java�EMain.ui.xml�A���ł�MainEntryPoint.java���i�܂�client�p�b�P�[�W���ƑS���j�폜���Ă����Ă����v�Ȃ悤���B
�v���W�F�N�g�̃v���p�e�B�[�́uGoogle�v���uWeb�c�[���L�b�g�v�́u�G���g���[�E�|�C���g�E���W���[���v��Main���폜����AMain.gwt.xml���s�v�ɂȂ�B[2010-09-19]
�܂��Awar/main/���폜�ł���B�i�G���g���[�|�C���g����`����Ă���ƁA����ɍ����j
�����N�ɂ���ĕʂ̉�ʂ֑J�ڂ�����ɂ́Aa�v�f�i�A���J�[�^�O�j��href�����Łuf:
url�v�����L�q����B[/2010-09-17]
<a href="${ f:url('/aaa/') }">�J�ڂ���</a>
�uf�v�́u<%@taglib prefix="f" uri="http://www.slim3.org/functions"%>
�v�ɂ���Đ錾����Ă���ASlim3��������̐ړ����B
�uf:
url�v�͑��p�X��URL���G���R�[�h���Ă����B
�J�ڌ� | �J�ڐ� | �L�q�� | ���l |
---|---|---|---|
�ǂ�����ł� | war/aaa/index.jsp |
<a href="${ f:url('/aaa/') }">�J�ڂ���</a> <a href="${ f:url('/aaa/index') }">�J�ڂ���</a> |
�u/�v����n�߂�ƁA���̃T�C�g���̐�p�X�����B �u/�v�ŏI���ƁAindex���ȗ����ꂽ�����B |
war/*.jsp | war/aaa/index.jsp |
<a href="${ f:url('aaa/') }">�J�ڂ���</a> <a href="${ f:url('aaa/index') }">�J�ڂ���</a> |
�u/�v����n�߂Ȃ��ƁA���p�X�B |
war/aaa/*.jsp | war/aaa/bbb.jsp |
<a href="${ f:url('/aaa/bbb') }">�J�ڂ���</a> <a href="${ f:url('bbb') }">�J�ڂ���</a> |
����f�B���N�g���[���̃y�[�W�ւ̑J�ځB |
war/aaa/*.jsp | war/aaa/index.jsp |
<a href="${ f:url('/aaa/index') }">�J�ڂ���</a> <a href="${ f:url('index') }">�J�ڂ���</a> <a href="${ f:url('./') }">�J�ڂ���</a> |
����f�B���N�g���[����index.jsp�ւ̑J�ځB |
war/aaa/*.jsp | war/index.jsp |
<a href="${ f:url('/') }">�J�ڂ���</a> <a href="${ f:url('../') }">�J�ڂ���</a> <a href="${ f:url('../index') }">�J�ڂ���</a> |
�z�[���y�[�W�i�g�b�v�y�[�W�j�ւ̑J�ځB |
������́i�o�^�j�����ʂ����ɂ́Aform�v�f��jsp�t�@�C���ɋL�q����B[2010-09-17]
�Q�l�F Slim3 ���{��T�C�g(�����)���t�H�[���̍쐬
<form method="post" action="${ f:url('inputAction') }"> <p><input type="text" ${ f:text("foo") }/></p> <p><input type="submit" value="�o�^"/></p> </form>
input�v�f�ɂ́Af:
text�Ef:
hidden�Ƃ������A�����̈ꕔ������Slim3�̊����p�ӂ���Ă���B
������type="submit"�͓��ɉ����p�ӂ���Ă��Ȃ��̂ŁA���̂܂�HTML���L�q����B
�iStruts����HTML�̃^�O�����̂܂ܒu��������J�X�^���^�O���p�ӂ���Ă������ASlim3�͂��������T�O�ł͂Ȃ��悤���j
���̂܂܂œ��̓G���A�͕\�������B
�������T�u�~�b�g�i�o�^�j�{�^���������ƁA404 NOT_FOUND�̃G���[�ɂȂ�Bform�^�O��action�����Ŏw�肵��URI�̏���������ĂȂ����瓖�R�O�O�G
�Ȃ��A�����l��^�������ꍇ�́A����JSP�ƃy�A�ɂȂ��Ă���Controller�̒��Œl���Z�b�g���Ă������B
public class InputController extends Controller {
@Override
public Navigation run() throws Exception {
requestScope("foo", "�����l");
return forward("input.jsp");
}
}
���͂��ꂽ�t�H�[������鏈�����쐬����B
�u�����N�v���W�F�N�g�ɓ����Ă���build.xml�́ugen-controller-without-view�v�����s����ƁAController�N���X���������B�ijsp�t�@�C���͍���Ȃ��j
�uaaa/inputAction�v�Ƃ����p�X�ɂ��Ă����ƁA�usrc/�`/server/controller/aaa/InputActionController.java�v�ƃe�X�g�p�\�[�X���o����B
package jp.hishidama.gae.slim3.ex1.server.controller.aaa;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
public class InputActionController extends Controller {
@Override
public Navigation run() throws Exception {
return null; �������P��null��Ԃ������i�J�ڐ悪�����j
}
}
���̐e�N���X�ł���Controller�ɂ́Arequest�Ƃ����t�B�[���h����`����Ă���B
�����ɂ��̓��e��\�����Ă݂悤�B
package jp.hishidama.gae.slim3.ex1.server.controller.aaa; import java.util.logging.Logger; import org.slim3.controller.Controller; import org.slim3.controller.Navigation; import org.slim3.util.RequestMap; public class InputActionController extends Controller { private final static Logger LOG = Logger.getLogger(InputActionController.class.getName()); @Override public Navigation run() throws Exception { RequestMap rm = new RequestMap(request); LOG.info(rm.toString()); return null; } }
RequestMap�Ƃ����̂́ASlim3�ŗp�ӂ���Ă��郆�[�e�B���e�B�[�BHashMap���p�����Ă���B
����Œ������Ă݂�ƁA���̉�ʂœ��͂��ꂽ�l�Ɩ��O�������Ă���̂�������B
�i���łɁuslim3.
�v�Ŏn�܂�v���p�e�B�[�������������Ă���悤���B���͉�ʂł͂������������O�͎g�p���Ȃ������ǂ������j
�Ȃ��Arun()��null��Ԃ��Ɛ^��������ʂ��\������邾���Ȃ̂ŁA�ʂ̉�ʂɑJ�ڂ���悤�ɂ��Ă����B
gen-controller�œo�^������ʁi/aaa/complete�j������Ă����āA�����փ��_�C���N�g����̂��ǂ������B
return redirect(basePath + "complete");
���āASlim3�̏ꍇ�ADB�o�^�Ȃǂ̏����́u�T�[�r�X�v�N���X�ōs���悤���B
�Ȃ̂ŁAService�N���X���쐬���AController����Service���Ăяo���悤�ɂ���B
�u�����N�v���W�F�N�g�ɓ����Ă���build.xml�́ugen-service�v�����s����ƃN���X���i�̈ꕔ�j����͂���_�C�A���O���J���B
�����ɃN���X���i�̈ꕔ�j����͂���ƁAService�N���X�Ƃ��̃e�X�g�N���X�������B
�Ⴆ�uaaa.
MyService�v�Ɠ��͂���Ɓusrc/�`/server/service/aaa/MyService.java�v�������B
package jp.hishidama.gae.slim3.ex1.server.service.aaa; public class MyService { }
���g�͉��������̂ŁO�O�G�A�����Ń��\�b�h��lj�����B
package jp.hishidama.gae.slim3.ex1.server.service.aaa; import java.util.Map; import java.util.logging.Logger; public class MyService { private final static Logger LOG = Logger.getLogger(MyService.class.getName()); public void regist(Map<String, Object> input) { LOG.info(input.toString()); } }
package jp.hishidama.gae.slim3.ex1.server.controller.aaa; import jp.hishidama.gae.slim3.ex1.server.service.aaa.MyService; import org.slim3.controller.Controller; import org.slim3.controller.Navigation; import org.slim3.util.RequestMap; public class InputActionController extends Controller { private MyService service = new MyService(); @Override public Navigation run() throws Exception { service.regist(new RequestMap(request)); return null; } }
���Ȃ݂�Controller�̃C���X�^���X�̓��N�G�X�g���ɍ����i�}���`�X���b�h�ŌĂ�Ȃ��j�悤�Ȃ̂ŁA�t�B�[���h�ɃC���X�^���X���������Ă��悢�B
Slim3�ŁiGAE�́jDB�Ƀf�[�^��o�^�i�ۑ��j����ׂɂ́A�u���f���v�N���X���g�p����B
���f���Ƃ́A�v�����JavaBeans�i�t�B�[���h�ɒl��ێ����A�Z�b�^�[�E�Q�b�^�[���\�b�h�Őݒ�E�擾����j�B
���f���̃C���X�^���X�Ƀf�[�^���Z�b�g���A��������̂܂�GAE��DB�ɕۑ�����B
�iModel�̐�����Slim3 ���{��T�C�g(�����)���f�[�^�N���X�̒�`�j
�u�����N�v���W�F�N�g�ɓ����Ă���build.xml�́ugen-model�v�����s����ƃN���X���i�̈ꕔ�j����͂���_�C�A���O���J���B
�����ɃN���X���i�̈ꕔ�j����͂���ƁAModel�N���X�Ƃ��̃e�X�g�N���X�A���ꂩ��Meta�Ƃ����N���X�������B
�Ⴆ�uaaa.
Data�v�Ɠ��͂���Ɓusrc/�`/shared/model/aaa/Data.java�v�usrc/�`/server/meta/aaa/DataMeta.java�v�������B
package jp.hishidama.gae.slim3.ex1.shared.model.aaa; import java.io.Serializable; import com.google.appengine.api.datastore.Key; import org.slim3.datastore.Attribute; import org.slim3.datastore.Model; @Model(schemaVersion = 1) public class Data implements Serializable { private static final long serialVersionUID = 1L;
@Attribute(primaryKey = true) private Key key; @Attribute(version = true) private Long version;
/** * Returns the key. * * @return the key */ public Key getKey() { return key; } �` }
GAE�Ƀf�[�^��o�^����ۂɂ́A�L�[�ƃo�[�W�������K�{�̂悤���B�Ȃ̂ŁA����Ɋւ���t�B�[���h�ƃZ�b�^�[�E�Q�b�^�[���\�b�h�������ŗp�ӂ���Ă���B
�����ɁA�����ŕK�v�Ƃ���t�B�[���h�ƃZ�b�^�[�E�Q�b�^�[���\�b�h��lj�����B
���̍ۂ̖��O�i�Z�b�^�[�E�Q�b�^�[���\�b�h�̖��O�A������v���p�e�B�[���j�́A���͌�JSP�iinput�v�f��name�����j�ɍ��킹�Ă����B
�������邱�Ƃɂ���āASlim3�̃��[�e�B���e�B�[���g���Ēl�̃R�s�[���ȒP�Ɏ����ł��邩��B
private String foo; �` /** * @return foo */ public String getFoo() { return foo; } /** * @param foo * �Z�b�g���� foo */ public void setFoo(String foo) { this.foo = foo; }
���t�B�[���h��Z�b�^�[�E�Q�b�^�[�͎����Œlj�����K�v�����邪�A����ɂ����Meta�N���X�������I�ɏ��������B
���̃��f���N���X���g����DB�ɓo�^���郍�W�b�N�́AService�N���X�ɋL�q����B
�i�g�����U�N�V�����̒��ŗ�O����������ƁA�����I�Ƀ��[���o�b�N�����炵���j
import org.slim3.datastore.Datastore; import org.slim3.util.BeanUtil; import com.google.appengine.api.datastore.Transaction; import jp.hishidama.gae.slim3.ex1.shared.model.aaa.Data; public class MyService { public Data regist(Map<String, Object> input) { Data data = new Data(); BeanUtil.copy(input, data); Transaction tx = Datastore.beginTransaction(); Datastore.put(data); tx.commit(); return data; //�l��Ԃ��Ă���̂́A�e�X�g���ɃL�[���擾�������� } }
public class MyServiceTest extends AppEngineTestCase {
�`
@Test
public void regist() {
Map<String, Object> input = new HashMap<String, Object>();
input.put("foo", "Hello");
Data data = service.regist(input);
Data stored = Datastore.get(Data.class, data.getKey());
assertThat(stored.getFoo(), is("Hello"));
}
}
DB�ɓo�^���ꂽ�l�̈ꗗ��\�������ʂ�����Ă݂�B[2010-09-18]
��ʂɕ\������l�́A����jsp��\������ׁiJSP�ւ̑J�ڑO�j�ɌĂ��Controller�ŗp�Ӂirequest�I�u�W�F�N�g�ɃZ�b�g�j����B
�Q�l�F Slim3 ���{��T�C�g(�����)���Ԃ₫�̈ꗗ�\��
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="f" uri="http://www.slim3.org/functions"%>
�`
<c:forEach var="e" items="${dataList}">
${f:h(e.foo)}<br>
</c:forEach>
�`
@Override
public Navigation run() throws Exception {
List<Data> dataList = new ArrayList<Data>();
{
Data g1 = new Data(); g1.setFoo("abc"); dataList.add(g1);
Data g2 = new Data(); g2.setFoo("������"); dataList.add(g2);
}
requestScope("dataList", dataList);
return forward("list.jsp");
}
�ŁA���ۂɂ�Service�N���X�̕���DB����f�[�^���擾���郁�\�b�h��p�ӂ��āA������Ăяo���B
private MyService service = new MyService(); �` @Override public Navigation run() throws Exception { List<Data> dataList = service.getList(); requestScope("dataList", dataList); return forward("list.jsp"); }
import org.slim3.datastore.Datastore; import jp.hishidama.gae.slim3.ex1.shared.model.aaa.Data; public class MyService { private DataMeta meta = new DataMeta(); �` public List<Data> getList() { return Datastore.query(meta).sort(meta.foo.asc).asList(); } }
Datastore.query()��ModelQuery�Ƃ����N���X��Ԃ��B
ModelQuery#sort()�Ń\�[�g���ڂ��w�肷��B���̎w��̎d���͖ʔ����ȁB
���ɂ�ModelQuery#filter()�Ńt�B���^�[�����iSQL�Ō���WHERE�����j���w��ł���悤���B
�Ō��ModelQuery#asList()���ĂԂ��Ƃɂ����DB�A�N�Z�X���s����B
�ꗗ�\������ɍ폜�@�\��lj����Ă݂�B[2010-09-23]
���݂̃f�[�^�ꗗ�̉E���ɍ폜�����N��u���B���̃����N���N���b�N����ƁA���̍s���폜�����B
<table border="1"> <tr> <th>�^�C�g��</th> <th>���e</th> <th>�쐬��</th> <th>�폜</th> </tr> <c:forEach var="e" items="${dataList}"> <tr> <td>${f:h(e.title)}</td> <td>${f:h(e.content)}</td> <td><fmt:formatDate value="${e.createDate}" pattern="yyyy-MM-dd" /></td> <c:set var="deleteUrl" value="delete?key=${f:h(e.key)}&version=${e.version}" /> <td><a href="${f:url(deleteUrl)}" onclick="return confirm('�폜���Ă����ł����H')">�폜</a></td> </tr> </c:forEach> </table>
package jp.hishidama.gae.slim3.ex1.server.controller.aaa; import jp.hishidama.gae.slim3.ex1.server.meta.aaa.DataMeta; import jp.hishidama.gae.slim3.ex1.server.service.aaa.MyService; import org.slim3.controller.Controller; import org.slim3.controller.Navigation;
public class DeleteController extends Controller { private DataMeta meta = DataMeta.get(); private MyService service = new MyService(); @Override public Navigation run() throws Exception { service.delete(asKey(meta.key), asLong(meta.version)); return redirect("list"); //�ꗗ�\����ʂɖ߂� } }
public class MyService { private DataMeta meta = new DataMeta(); �` public void delete(Key key, Long version) { Transaction tx = Datastore.beginTransaction(); Data data = Datastore.get(tx, meta, key, version); Datastore.delete(tx, data.getKey()); Datastore.commit(tx); } }
�܂��Acontroller�p�b�P�[�W������AppRouter�Ƃ����N���X�������URL�}�b�s���O��ύX���Ă����ƁA�ʂ�URI�`���udelete/�L�[/�o�[�W�����v�ō폜���w�肷�邱�Ƃ��o����B
<c:set var="deleteUrl" value="delete/${f:h(e.key)}/${e.version}" />
<td><a href="${f:url(deleteUrl)}" onclick="return confirm('�폜���Ă����ł����H')">�폜</a></td>
package jp.hishidama.gae.slim3.ex1.server.controller;
import org.slim3.controller.router.RouterImpl;
public class AppRouter extends RouterImpl {
/** �R���X�g���N�^�[ */
public AppRouter() {
addRouting(
"/{app}/delete/{key}/{version}",
"/{app}/delete?key={key}&version={version}"
);
}
}
�u/aaa/delete/�L�[/�o�[�W�����v�Ƃ������N�G�X�g������ƁA�u/aaa/delete?key=�L�[&version=�o�[�W�����v�Ƃ����`�ɒu�������Ă���Controller���Ăяo�����悤�ɂȂ�B
Slim3�iGAE�j�ł͓��t�͕W�����ň�����̂ŁA���{���ԁiJST�j�Ƃ���Ă���B[2010-09-18]
�����f�[�^�Ƃ��Ă͂���ł����Ƃ��Ă��A�\������ۂ͓��{�l�Ƃ��Ă͓��{���Ԃ̕����s����������Ȃ����Ǝv���B
JSP�ŕ\������ۂ�Date�^�̒l��ϊ����Ă��B �iSlim3��GAE�̋@�\�ł͂Ȃ��AJSTL�̓��t�t�H�[�}�b�g���g�p����j
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<fmt:formatDate value="${createDate}" pattern="yyyy-MM-dd HH:mm:ss" timeZone="JST"/>
<fmt:setTimeZone value="JST"/> <fmt:formatDate value="${createDate}" pattern="yyyy-MM-dd HH:mm:ss z"/>
Slim3�ł́A�ȒP�ȃo���f�[�V�����t���[�����[�N������Ă���B[2010-09-18]
�Q�l�F Slim3 ���{��T�C�g(�����)���o���f�[�V����
���͂��t����Controller�̒��Œl���`�F�b�N���A�G���[����������G���[��ʂ֑J�ڂ���B
�` import org.slim3.controller.validator.Validators; �` public class InputActionController extends Controller { �` @Override public Navigation run() throws Exception { if(!validate()){ return forward("input"); //�G���[���N�����ꍇ�̑J�ڐ�B�����ł͌��̓��͉�� } service.regist(new RequestMap(request)); return redirect(basePath + "complete"); } boolean validate() { Validators v = new Validators(request); v.add("foo", v.required()); v.add("bar", v.required(), v.maxlength(100)); v.add("zzz", v.required(), v.integerType(), v.longRange(1, Integer.MAX_VALUE)); return v.validate(); } }
Validators�̃C���X�^���X�����ۂ�request��n���Ă���̂ŁA�������W�b�N��g�ݍ��ނ̂�Controller�N���X�ł����A�Ǝv���B
v.add()�̑�1�����ɓ��͉�ʂ̊e���ڂ̖��O�i<input name="foo">�Ƃ��j���w�肵�A��2�����ȍ~�ɂ͐������e���w�肷��B
required()���K�{�`�F�b�N�Amaxlength()���ő啶�����`�F�b�N�AintegerType()�͐����`�F�b�N�AlongRange()�͔͈̓`�F�b�N�ƁA��ϕ�����Ղ��B
�G���[�����������v.validate()��false��Ԃ��B
�܂��AController#errors�iv.getErrors()�ŕԂ����̂Ɠ����C���X�^���X�j�̒��ɃG���[���b�Z�[�W���Z�b�g�����B
�G���[���b�Z�[�W��\������ɂ́A�ȉ��̂悤�ɋL�q����B
�i�����ł͌��̓��͉�ʂɃG���[���b�Z�[�W��\������z��j
<head>
�`
<style type="text/css">
input.err { background-color: pink; }
span.err { color: red; }
</style>
</head>
<%-- �G���[���b�Z�[�W���܂Ƃ߂ĕ\������� --%> <c:if test="${not empty errors}"> <ul> <c:forEach var="e" items="${f:errors()}"> <li><span class="err">${f:h(e)}</span></li> </c:forEach> </ul> </c:if>
<%-- �ʂ̃G���[���b�Z�[�W��\������� --%> foo�F <input type="text" ${ f:text("foo") } class="${f:errorClass('foo', 'err')}"/> <c:if test="${not empty errors.foo}"><span class="err">�G���[�F${f:h(errors.foo)}</span></c:if> <br> bar�F <input type="text" ${ f:text("bar") } class="${f:errorClass('bar', 'err')}"/> <c:if test="${not empty errors.bar}"><span class="err">�G���[�F${f:h(errors.bar)}</span></c:if> <br> zzz�F <input type="text" ${ f:text("zzz") } class="${f:errorClass('zzz', 'err')}"/> <c:if test="${not empty errors.zzz}"><span class="err">�G���[�F${f:h(errors.zzz)}</span></c:if>
�܂��Aapplication_ja.properties���́uvalidator.
�v�Ŏn�܂�v���p�e�B�[�̕���������������A�G���[���b�Z�[�W�S�ʂ�Ǝ��ɒ�`���邱�Ƃ��o����B
validator.required={0}�͕K�{�ł��B validator.byteType={0}�̓o�C�g�łȂ�������܂���B validator.shortType={0}�͒Z�����łȂ�������܂���B validator.integerType={0}�͐����łȂ�������܂���B validator.longType={0}�͒������łȂ�������܂���B validator.floatType={0}�͒P���x�����łȂ�������܂���B validator.doubleType={0}�͔{���x�����łȂ�������܂���B validator.numberType={0}�͐��l({1})�ł͂���܂���B validator.dateType={0}�͓��t({1})�ł͂���܂���B validator.minlength={0}�̒������ŏ��l({1})�����ł��B validator.maxlength={0}�̒������ő�l({1})���Ă��܂��B validator.range={0}��{1}��{2}�̊ԂłȂ�������܂���B validator.regexp={0}���s���ł��B
GAE��HTTP�Z�b�V�������g�p����ɂ́Aappengine-web.xml��ݒ肵�Ă����K�v������B[2010-09-19]
<?xml version="1.0" encoding="utf-8"?> <appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> �` <sessions-enabled>true</sessions-enabled> �c�f�t�H���g��false </appengine-web-app>
Slim3�̏ꍇ�AController�N���X�ł́irequest�Ɠ��l�ɁjsessionScope()�Ƃ������\�b�h���p�ӂ���Ă���̂ŁA�l�̐ݒ�E�擾�ɂ͂�����g���̂��֗��B
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@
�@