解析视频的网站怎么做,wordpress 装饰公司,怎么购买域名自己做网站,网上推销产品的软件js webapp://这是Project Student的一部分。 其他职位包括具有Jersey的 Web服务 客户端#xff0c;具有Jersey的 Web服务服务器 #xff0c; 业务层 #xff0c; 具有Spring数据的持久性 #xff0c;分片集成测试数据 #xff0c; Webservice集成和JPA标准查询 。 当我开… js webapp:// 这是Project Student的一部分。 其他职位包括具有Jersey的 Web服务 客户端具有Jersey的 Web服务服务器 业务层 具有Spring数据的持久性 分片集成测试数据 Webservice集成和JPA标准查询 。 当我开始这个项目时我有四个目标。 他们没有特别的顺序 了解jQuery和其他AJAX技术。 为此我需要一个了解的REST服务器 捕获最近获得的有关球衣和挂毯的知识 创建一个我可以用来了解其他技术例如spring MVCrestletnetty的框架以及 在工作面试中有什么要讨论的 如果对其他人有用–太好了 这就是为什么它在Apache许可下可用。 不言而喻可接受的用途不包括在没有适当归因的情况下将“ Project Student”变成学生项目 学习AJAX的问题是我一开始会不确定问题的根源。 jQuery不好吗 不良的REST服务 还有吗 广泛的单元和集成测试是一个好的开始但是始终会存在一些不确定性。 另一个考虑因素是在现实世界中我们经常需要对数据库的基本视图。 它不会供公众使用-当我们遇到WTF时刻时仅供内部使用。 它也可以用来维护我们不想通过公共界面管理的信息例如下拉菜单中的值。 对此可以稍作调整以提供适度的可伸缩性。 将大型服务器用于数据库和REST服务然后让N台前端服务器运行常规的Web应用程序充当用户和REST服务之间的中介。 前端服务器可以是相当轻量的并且可以根据需要旋转。 将缓存服务器放置在前端和REST服务器之间的加分点因为将读取压倒性的点击量。 这种方法无法扩展到Amazon或Facebook的规模但是对于许多站点来说已经足够了。 维护Webapp 这将我们带到了webapp onion的可选层–一个常规的webapp充当REST服务的前端。 由于各种原因我在应用程序中使用Tapestry 5 但这是一个任意决定我不会花很多时间研究Tapestry特定的代码。 您可以使用创建新的挂毯项目 $ mvn archetype:generate -DarchetypeCataloghttp://tapestry.apache.org 我已经在http://jumpstart.doublenegative.com.au/jumpstart/examples/找到了有价值的示例。 在适当的地方我会注明出处。 稍后我还将创建webapp的第二个可选层–使用Selenium和WebDriver 即Selenium 2.0进行功能和回归测试。 局限性 只读 –分解webapp需要进行大量工作因此初始版本将仅提供对简单表的只读访问。 没有更新没有一对多映射。 用户身份验证 –尚未进行身份验证的工作。 加密 -尚未对通信进行加密。 数据库锁 –我们在Hibernate版本中使用机会锁定而不是显式数据库锁定。 安全说明根据最少公开的原则除非需要否则我们不想使该版本可见。 一个好的规则是您将看到它是否请求一个特定的对象但看不到列表中的对象。 REST客户端 -每种类型的默认GET处理程序非常粗糙-仅返回对象列表。 我们需要一个更复杂的响应例如记录数开始和结束索引状态码等并将让UI驱动它。 目前我们真正需要的只是一个计数我们可以只请求列表并计数元素的数量。 目标 我们需要一个列出数据库中所有课程的页面。 它不必担心分页排序等问题。它应该具有用于编辑和删除记录的链接可能是无效的。 它不需要添加新课程的链接。 该页面应如下所示 课程模板 Tapestry页面上列出的课程很简单–它基本上只是修饰的值网格 。 有关Layout.tml等信息请参见挂毯原型。 html t:typelayout titleCourse Listt:sidebarTitleFramework Versionxmlns:thttp://tapestry.apache.org/schema/tapestry_5_3.xsdxmlns:ptapestry:parameter!-- Most of the page content, including head, body, etc. tags, comes from Layout.tml --t:zone t:idzone pCourse page/pt:grid sourcecourses rowcourse includeuuid,name,creationdate addedit,deletep:namet:pagelink pageCourseEditor contextcourse.uuid${course.name}/t:pagelink/p:namep:editcellt:actionlink t:idedit contextcourse.uuidEdit/t:actionlink/p:editcellp:deletecellt:actionlink t:iddelete contextcourse.uuidDelete/t:actionlink/p:deletecellp:emptypThere are no courses to display; you can t:pagelink pageCourse/Editor parameters{ mode:create, courseUuid:null }add some/t:pagelink./p/p:empty/t:grid/t:zonep:sidebarp[t:pagelink pageIndexIndex/t:pagelink]br/[t:pagelink pageCourse/ListCourses/t:pagelink]/p/p:sidebar
/html 具有的属性文件 titleCourses
delete-courseDelete course? 我已经包括了用于编辑和删除的操作链接但是它们不起作用。 GridDataSources 我们的页面需要显示值的来源。 这需要两个类。 第一个定义了上面使用的课程属性。 package com.invariantproperties.sandbox.student.maintenance.web.tables;import com.invariantproperties.sandbox.student.business.CourseFinderService;public class GridDataSources {// Screen fieldsPropertyprivate GridDataSource courses;// Generally useful bits and piecesInjectprivate CourseFinderService courseFinderService;InjectComponentprivate Grid grid;// The codevoid setupRender() {courses new CoursePagedDataSource(courseFinderService);}
} 实际的实现是 package com.invariantproperties.sandbox.student.maintenance.web.tables;import com.invariantproperties.sandbox.student.business.CourseFinderService;
import com.invariantproperties.sandbox.student.domain.Course;
import com.invariantproperties.sandbox.student.maintenance.query.SortCriterion;
import com.invariantproperties.sandbox.student.maintenance.query.SortDirection;public class CoursePagedDataSource implements GridDataSource {private int startIndex;private ListCourse preparedResults;private final CourseFinderService courseFinderService;public CoursePagedDataSource(CourseFinderService courseFinderService) {this.courseFinderService courseFinderService;}Overridepublic int getAvailableRows() {long count courseFinderService.count();return (int) count;}Overridepublic void prepare(final int startIndex, final int endIndex, final ListSortConstraint sortConstraints) {// Get a page of courses - ask business service to find them (from the// database)// ListSortCriterion sortCriteria toSortCriteria(sortConstraints);// preparedResults courseFinderService.findCourses(startIndex,// endIndex - startIndex 1, sortCriteria);preparedResults courseFinderService.findAllCourses();this.startIndex startIndex;}Overridepublic Object getRowValue(final int index) {return preparedResults.get(index - startIndex);}Overridepublic ClassCourse getRowType() {return Course.class;}/*** Converts a list of Tapestrys SortConstraint to a list of our business* tiers SortCriterion. The business tier does not use SortConstraint* because that would create a dependency on Tapestry.*/private ListSortCriterion toSortCriteria(ListSortConstraint sortConstraints) {ListSortCriterion sortCriteria new ArrayList();for (SortConstraint sortConstraint : sortConstraints) {String propertyName sortConstraint.getPropertyModel().getPropertyName();SortDirection sortDirection SortDirection.UNSORTED;switch (sortConstraint.getColumnSort()) {case ASCENDING:sortDirection SortDirection.ASCENDING;break;case DESCENDING:sortDirection SortDirection.DESCENDING;break;default:}SortCriterion sortCriterion new SortCriterion(propertyName, sortDirection);sortCriteria.add(sortCriterion);}return sortCriteria;}
}应用模块 现在有了GridDataSource我们可以看到它的需求– CourseFinderService。 虽然存在Tapestry-Spring集成但我们希望保持维护Webapp尽可能薄所以现在我们使用标准Tapestry注入。 package com.invariantproperties.sandbox.student.maintenance.web.services;import com.invariantproperties.sandbox.student.business.CourseFinderService;
import com.invariantproperties.sandbox.student.business.CourseManagerService;
import com.invariantproperties.sandbox.student.maintenance.service.impl.CourseFinderServiceTapestryImpl;
import com.invariantproperties.sandbox.student.maintenance.service.impl.CourseManagerServiceTapestryImpl;/*** This module is automatically included as part of the Tapestry IoC Registry,* its a good place to configure and extend Tapestry, or to place your own* service definitions.*/
public class AppModule {public static void bind(ServiceBinder binder) {binder.bind(CourseFinderService.class, CourseFinderServiceTapestryImpl.class);binder.bind(CourseManagerService.class, CourseManagerServiceTapestryImpl.class);}....
} 请注意我们正在将标准CourseFinderService接口与挂毯特定的实现一起使用。 这意味着我们可以直接使用标准实现只需要对配置文件进行一点改动即可 CourseFinderServiceTapestryImpl CourseFinderService接口的本地实现必须使用REST客户端而不是Spring Data实现。 使用较早使用的由外而内的方法Tapestry模板的需求应驱动服务实现的需求进而驱动REST客户端和服务器的需求。 package com.invariantproperties.sandbox.student.maintenance.service.impl;public class CourseFinderServiceTapestryImpl implements CourseFinderService {private final CourseFinderRestClient finder;public CourseFinderServiceTapestryImpl() {// resource should be loaded as tapestry resourcefinal String resource http://localhost:8080/student-ws-webapp/rest/course/;finder new CourseFinderRestClientImpl(resource);// load some initial datainitCache(new CourseManagerRestClientImpl(resource));}Overridepublic long count() {// FIXME: grossly inefficient but good enough for now.return finder.getAllCourses().length;}Overridepublic long countByTestRun(TestRun testRun) {// FIXME: grossly inefficient but good enough for now.return finder.getAllCourses().length;}Overridepublic Course findCourseById(Integer id) {// unsupported operation!throw new ObjectNotFoundException(id);}Overridepublic Course findCourseByUuid(String uuid) {return finder.getCourse(uuid);}Overridepublic ListCourse findAllCourses() {return Arrays.asList(finder.getAllCourses());}Overridepublic ListCourse findCoursesByTestRun(TestRun testRun) {return Collections.emptyList();}// method to load some test data into the database.private void initCache(CourseManagerRestClient manager) {manager.createCourse(physics 101);manager.createCourse(physics 201);manager.createCourse(physics 202);}
} 我们的JPA Criteria查询可以快速计数但是我们的REST客户端尚不支持。 结语 完成艰苦的工作后我们将获得一个维护文件.war。 我们可以使用webservice .war在我们的应用服务器上部署它也可以不部署。 除了Web服务的临时硬编码URL外这两个.war文件没有理由必须位于同一系统上。 我们首先应该去http// localhost8080 / student-maintenance-webapp / course / list。 我们应该看到如上所示的简短课程列表。 在那种情况下我已经重新启动了webapp三次因此每个条目都会重复三倍。 现在我们应该访问位于http// localhost8080 / student-ws-webapp / rest / course的webservice webapp并验证我们是否也可以通过浏览器获取数据。 经过一些清理后我们应该看到 {course:[{creationDate:2013-12-28T14:40:21.369-07:00,uuid:500069e4-444d-49bc-80f0-4894c2d13f6a,version:0,name:physics 101},{creationDate:2013-12-28T14:40:21.777-07:00,uuid:54001b2a-abbb-4a75-a289-e1f09173fa04,version:0,name:physics 201},{creationDate:2013-12-28T14:40:21.938-07:00,uuid:cfaf892b-7ead-4d64-8659-8f87756bed62,version:0,name:physics 202},{creationDate:2013-12-28T16:17:54.608-07:00,uuid:d29735ff-f614-4979-a0de-e1d134e859f4,version:0,name:physics 101},....]
}源代码 源代码位于https://github.com/beargiles/project-student [github]和http://beargiles.github.io/project-student/ [github页面]。 参考 项目学生 Invariant Properties博客上来自JCG合作伙伴 Bear Giles的Maintenance Webapp只读 。 翻译自: https://www.javacodegeeks.com/2014/01/project-student-maintenance-webapp-read-only.htmljs webapp://