php 简单mvc框架
使用Java for Web时,有许多可能的基于MVC操作的框架。 VRaptor就是其中之一。 它的新第四版基于CDI 1.1 。 本文将带您浏览框架的原理和版本新颖性。
在VRaptor上启动第一个控制器所需要做的就是用@Controller注释类,并且该框架将依靠其URL和JSP约定,因此您可以使用尽可能少的配置。 这是一个例子:
@Controller
public class UserController {
public void list() { //... }
}
VRaptor的URL约定为controllerName / methodName,因此list方法可通过用户/ list访问。 注意,路由上不考虑控制器后缀。
JSP调度遵循另一个有用的约定。 它与URL约定非常相似:执行控制器方法后,VRaptor将在服务器上查找JSP。
WEB-INF / jsp / controllerName / methodName.jsp。
在我们的示例中,它将是
WEB-INF / jsp / user / list.jsp。
您的控制器的所有公共方法都将遵循这些约定进行映射,并且无论所使用的HTTP动词如何,都将响应请求。
您还可以使用@ Get,@ Post,@ Put或@Delete批注根据您选择的动词来限制对控制器方法的访问。
如果您选择不使用URL约定,则还可以向这些注释添加String参数,以更改将到达它们的URL路由,如果您想为HTTP动词无限制方法自定义de URL,则可以使用@路径注释。
@Get("any/other/url")
public void list() { //... }
您可以在控制器方法上接收参数,VRaptor将尝试填充这些值。 这将适用于简单的值,例如此搜索方法中的long:
@Get
public void search(long id) { //... }
如果请求中有任何名为id的参数,即与方法参数同名,则VRaptor会尝试将参数转换为期望的类型。 可以通过user / search?id = 1 URL来访问此方法,或者甚至可以使用参数化的URL:
@Get("user/search/{id}")
public void search(long id) { //... }
在这种情况下,示例URL将为user / search / 1。
这是一个开始,但是我们也可以从视图中获取更复杂的对象,如在获取用户的此add方法上所看到的:
@Post
public void add(User user) { //... }
将调用该方法的form.jsp应该如下所示:
<form action="user/add" method="post">
<input type="text" name="user.name"/>
<input type="text" name="user.email"/>
<input type="submit" value="Create user">
</form>
此表单的请求参数示例可以是:
user.name = Rodrigo Turini
user.email = rodrigo.turini@caelum.com.br
...
为了使对象在JSP上可访问,我们可以简单地在controller方法上将它们返回:
@Get
public List<User> list(){
return userDao.list();
}
由于我们要返回List <User>,因此视图上的变量名称将为$ {userList}。 如果我们的返回类型是单个User对象,则视图变量将为$ {user}。 使用专家界面,还有另一种可以将对象发送到视图的方式:结果。 我们可以将此bean注入到控制器中,并使用其include方法:
@Controller
public class UserController {
@Inject private Result result;
@Inject private UserDao userDao;
@Get
public void list(){
List<User> list = userDao.list();
result.include(list);
result.include("users", list);
}
}
上面的代码两次包含相同的列表,以解释两个选项及其差异。 第一个include将在JSP上提供一个名为$ {userList}的变量,就像方法return一样。 第二个包含对象的名称,因此可以通过$ {users}访问它。
还有许多其他Result方法可以帮助我们处理视图。 检查返回序列化为JSON的对象列表有多么简单:
@Get
public void jsonList(){
List<User> users = userDao.list();
result.use(json()).from(users).serialize();
}
json方法来自Results类,该类为我们提供了最常见结果类型的方法,例如xml,html,jsonp。 还有一个表示方法,其行为将与请求的接受格式相对应。
到目前为止,我们看到的所有内容都可以轻松配置。 因为您的类是CDI托管的bean,所以我们可以专门化任何VRaptor组件-并且它们被巧妙地封装。 例如,为了更改默认的渲染视图或更改VRaptor将查找的位置,您要做的就是专门设置DefaultPathResolver:
@Specializes
public class CustomPathResolver extends DefaultPathResolver {
@Override
protected String getPrefix() {
return "/root/folder/";
}
}
我们可以同样地更改URL约定,从而覆盖PathAnnotationRoutesParser。
CDI集成的另一个有趣的方面是管理项目的外部类变得多么简单。 例如,将VRaptor与JPA集成是一个非常简单的过程。 您可以编写一个如下所示的EntityManager生产者:
public class EntityManagerCreator {
@Inject private EntityManagerFactory factory;
@Produces @RequestScoped
public EntityManager getEntityManager() {
return factory.createEntityManager();
}
public void destroy(@Disposes EntityManager em) {
if (em.isOpen()) {
em.close();
}
}
}
而已。 现在,您的应用程序中的任何bean都可以注入该对象的实例:
public class UserDao {
@Inject private EntityManager em;
public void add(User user) {
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit()
}
// ...
}
我们还可以创建一个简单的拦截器以查看一个开放的事务。 一个例子是:
@Intercepts
public class JPATransactionInterceptor {
@Inject private EntityManager manager;
@AroundCall
public void intercept(SimpleInterceptorStack stack) {
EntityTransaction transaction = manager.getTransaction();
transaction.begin();
stack.next();
transaction.commit();
}
}
请注意,以@AroundCall注释的拦截方法将接收SimpleInterceptorStack作为参数。 调用next()方法将分派给控制器,因此我们需要在它之前打开事务并在它之后提交事务。
和前一种方法一样简单的方法是支持@Transactional注释,并将该拦截方法仅应用于带有注释的方法。 您需要做的就是向拦截器添加一个accepts方法:
@Accepts
public boolean accepts() {
return method.containsAnnotation(Transactional.class);
}
那是! UserController上的add方法就是一个示例:
@Controller
public class UserController {
@Inject private Result result;
@Inject private UserDao userDao;
@Get
public void list() {
List<User> list = userDao.list();
result.include(list);
result.include("users", list);
}
@Post @Transactional
public void add(User user) {
userDao.add(user);
}
}
现在,UserDao方法可以简单地委托给EntityManager.persist:
public void add(User user) {
em.persist(user);
}
这些功能和许多其他功能已作为VRaptor4插件实现并分发。 上面提到的拦截器和生产器放置在vraptor-jpa和vraptor-hibernate插件上,使用它们所需要做的就是在我们的项目中添加其jar(甚至配置您最喜欢的依赖项管理器)。 无需额外的配置!
只要插件具有bean.xml文件,CDI就会管理其类并使它们可用于注入VRaptor。 由于创建扩展非常容易,因此社区参与度很高,并且已经创建了许多插件。 其中一些可以在此页面的框架文档中找到 。
如果您在应用程序服务器中,那么使用JPA和事务控制的工作将变得更加简单。 您可以使用@PersistenceContext而不是CDI的@Inject注入EntityManager。 因此,您可以使用javax.transaction.Transactional批注来控制方法的事务,即:
@Controller
public class UserController {
@Inject private Result result;
@Inject private UserDao userDao;
@Get
public void list(){
List<User> list = userDao.list();
result.include("users", list);
}
@Post @Transactional
public void add(User user){
userDao.add(user);
}
@Post @Transactional
public void remove(User user){
userDao.delete(user);
}
}
或者,如果您愿意,可以使用@Transactional来注释您的VRaptor的控制器,而不是注释您的方法,如下所示:
@Controller @Transactional
public class UserController {
@Inject private Result result;
@Inject private UserDao userDao;
// remaining code
}
这是可能的,因为您的VRaptor的Controller以及您想要的所有其他类都是CDI管理的bean。
动手学习VRaptor4
您可以以动手方式学习有关框架的更多信息,查看基于VRaptor4构建的开源项目。 问答引擎Mamute是一个很好的例子,它充分利用了第4版功能,如项目库中所示 。 还有框架的测试应用程序vraptor-music-jungle和提供的blank-project (一个预先配置的基础项目),可以让您快速入门。
您可以在其文档中找到有关该框架的更多信息:从1 分钟指南和10分钟指南开始,检查从先前版本教程进行的迁移,并浏览社区编写的食谱 。 如果您想进一步研究,还请阅读有关与VRaptor核心无缝集成的CDI 1.1规范和功能的更多信息。
php 简单mvc框架