Magdeburger Developer Days 2017 - Hendrik Pilz
Ich werde nicht von Google bezahlt oder unterstützt.
Just Code 4 Fun & Profit ;-)
Standard | Flexible |
---|---|
stable | beta |
Java 7 | Java 8 |
Google Container | Docker Container |
Java Servlet 2.5 | individuell |
/src/main/java -> Java Code /src/main/webapp -> JSPs /src/main/webapp/WEB-INF/appengine-web.xml /src/main/webapp/WEB-INF/web.xml /src/test/java -> Unit Tests /pom.xml -> Maven-Konfiguration
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>gaecms-demo</application>
<version>1</version>
<threadsafe>true</threadsafe>
<sessions-enabled>true</sessions-enabled>
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
WEB-INF/appengine-web.xml
cloud.google.com/appengine/docs/standard/java/config/appref
.level = INFO
WEB-INF/logging.properties
groupId:artifactId:version
groupId:artifactId:version
<build>
[...]
<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.9.46</version>
<configuration>
<jvmFlags>
<jvmFlag>-Xdebug</jvmFlag>
<jvmFlag>-Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=n</jvmFlag>
</jvmFlags>
<disableUpdateCheck>true</disableUpdateCheck>
</configuration>
</plugin>
[...]
</build>
Maven Build
<web-app [...]>
[...]
<security-constraint>
<web-resource-collection>
<web-resource-name>admin</web-resource-name>
<url-pattern>/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
[...]
</web-app>
Geschützter Bereich in web.xml
<% if (request.isUserInRole("admin")) {
UserService userService = UserServiceFactory.getUserService();
%>
<li><a href="/admin/Write">Write Blog</a></li>
<li><a href="/admin/MediaLibrary">Media Library</a></li>
<li><a href="<%= userService.createLogoutURL("/")%>">Logout</a></li>
<% }%>
Geschützter Bereich in JSP-Datei
public class ObjectifyHelper implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ObjectifyService.register(BlogEntry.class);
ObjectifyService.register(Comment.class);
ObjectifyService.register(MediaFile.class);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// do nothing
}
}
ObjectifyHelper registriert Entity-Klassen
<web-app [...]>
[...]
<listener>
<listener-class>de.hepisec.gaecms.ObjectifyHelper</listener-class>
</listener>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[...]
</web-app>
Objectify in web.xml aktivieren
@Entity
public class BlogEntry {
@Id
private String id;
@Index
private Date dateCreated = new Date();
@Index
private Date datePublished = null;
@NotNullOrEmpty
private String title;
@NotNullOrEmpty
private String text;
@Load
private List<Ref<Comment>> comments;
/** Getter, Setter etc. **/
}
Objectify Entity
github.com/objectify/objectify/wiki/Entities
public List<Ref<Comment>> getCommentsRef() {
return comments;
}
public List<Comment> getComments() {
List<Comment> commentObjects = new ArrayList<>();
for (Ref<Comment> ref : comments) {
commentObjects.add(ref.get());
}
return commentObjects;
}
public void setComments(List<Ref<Comment>> comments) {
this.comments = comments;
}
Getter / Setter für List<Ref<Comment>> comments;
Code sagt mehr als 1000 Worte
$ ./google-cloud-sdk/install.sh
$ gcloud config set project gaecms-demo
$ gcloud auth application-default login
Installation und Authentifizierung des Google Cloud SDK
private String getContent() {
Storage storage = StorageOptions.getDefaultInstance().getService();
try {
BlobId blobId = BlobId.of(getBucket(), id);
if (null == storage.get(blobId)) {
return "";
}
return new String(storage.readAllBytes(blobId), "UTF-8");
} catch (StorageException | UnsupportedEncodingException ex) {
Logger.getLogger(EditableContent.class.getName()).log(Level.WARNING, ex.getMessage(), ex);
return "";
}
}
Cloud Storage lesen
Storage storage = StorageOptions.getDefaultInstance().getService();
BlobId blobId = BlobId.of(getBucket(), id);
byte[] content = pContent.getBytes("UTF-8");
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();
try (WriteChannel writer = storage.writer(blobInfo)) {
writer.write(ByteBuffer.wrap(content, 0, content.length));
}
Cloud Storage schreiben
<cms:EditableContent id="impressum" mode="inline" />
<cms:EditableContent id="datenschutz" mode="markdown" />
<cms:EditableContent id="html-text" mode="html" />
<cms:EditableContent id="plain-text" mode="plain" />
public class BlogEntryControllerTest {
private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
protected Closeable session;
@BeforeClass
public static void setUpClass() {
ObjectifyService.setFactory(new ObjectifyFactory());
}
@Before
public void setUp() {
session = ObjectifyService.begin();
ObjectifyService.register(BlogEntry.class);
helper.setUp();
}
@After
public void tearDown() {
session.close();
helper.tearDown();
}
/** Tests **/
}
Diese Präsentation ist hier verfügbar
www.hepisec.de/devdays-2017/