文档章节

play1.x 第三弹 :控制器层(Controllers)

星闪
 星闪
发布于 2017/08/07 17:21
字数 2214
阅读 12
收藏 0
点赞 0
评论 0

谨以此系列文章进行学习、记录、分享。

注:参考了play官方文档    https://www.playframework.com/documentation/1.2.x/home

   

 controller其实就是一个调度员,在一个请求过来的时候,来协调多个资源(对象),它使用与模型层同一种语言,以便访问和修改模型对象,但同时它又跟HTTP接口一样,是面向请求(Request)和响应(Response)的。

    controller主要做的事情就是:接受请求参数,处理请求,响应请求。

controller的创建

    一个Controller就是一个位于 controllers 包(或子包)中的类,其继承于 play.mvc.Controller :

    示例:

package controllers;
 
import models.Client;
import play.mvc.Controller;
 
public class Clients extends Controller {
 
    public static void show(Long id) {
        Client client = Client.findById(id);
        render(client);
    }
 
    public static void delete(Long id) {
        Client client = Client.findById(id);
        client.delete();
    }
 
}

 Controller中每一个public static方法都被称为一个action。它的格式如:

public static void action_name(params...);

参数的接收

1.params对象

它是在 play.mvc.Controller 中定义的。这个对象中,包含了当前请求的所有数据。

示例:

public static void show() {
    String id = params.get("id");
    String[] names = params.getAll("names");
}

你还可以转换参数值的类型:

public static void show() {
    Long id = params.get("id", Long.class);
}

2.直接利用action方法的参数类型定义来转换 

我们可以直接从action方法的参数定义中,直接拿到对应的参数值。方法中的参数名必须跟http传过来的参数名相同。

比如,对于如下的URL:

/clients?id=1451

我们可以定义一个包含 id 参数的action:

public static void show(String id) {
    System.out.println(id); 
}

 内部原理是,Play会对每个action进行扫描,得到其参数信息(包括类型与参数名)。能过反射很容易得到参数类型,但得不到参数名,因为javac在编译java代码时,会忽略参数名信息。而Play内置了eclipse的编译器,并在编译时打开相关选项以记录参数名信息,所以才能成功取到。

HTTP to Java 高级绑定

简单类型

Java中所有基础和常用类型,都可以自动绑定:

intlongbooleancharbytefloatdoubleIntegerLongBooleanCharStringByteFloatDouble.

Date

如果一个日期格式如下,则它可以自动转换并绑定:

  • yyyy-MM-dd’T’hh:mm:ss’Z' // ISO8601 + timezone
  • yyyy-MM-dd’T’hh:mm:ss" // ISO8601
  • yyyy-MM-dd
  • yyyyMMdd’T’hhmmss
  • yyyyMMddhhmmss
  • dd'/‘MM’/'yyyy
  • dd-MM-yyyy
  • ddMMyyyy
  • MMddyy
  • MM-dd-yy
  • MM'/‘dd’/'yy

使用@As注解,我们可以指定日期格式。

例如:

archives?from=21/12/1980
public static void articlesSince(@As("dd/MM/yyyy") Date from) {
    List<Article> articles = Article.findBy("date >= ?", from);
    render(articles);
}

如果没有使用@As注解,则Play将使用你的区域对应的默认日期格式。

文件(File) 

在Play中处理文件上传非常简单。使用经 multipart/form-data 编码的请求将文件post到服务器端,同时使用 java.io.File 来获取文件:

public static void create(String comment, File attachment) {
    String s3Key = S3.post(attachment);
    Document doc = new Document(comment, s3Key);
    doc.save();
    show(doc.id);
}

Play将先取得上传的文件,保存在临时目录下,并使用上传的文件名。当这个request结束后,该文件将被删除,所以我们必须将它拷贝到一个安全的目录中,否则就找不到了。

Map<String, String>

public static void show(Map<String, String> client) {
    …
}

一个如下的query string:

?client.name=John&client.phone=111-1111&client.phone=222-2222

将会把变量client绑定到一个含有两个元素的map上。第一个元素的key是 name ,值是 John ,第二个key是 phone 值是 111-1111, 222-2222.

POJO对象绑定

Play还可以使用简单的命名约定将参数绑定到一个pojo对象上。

public static void create(Client client ) {
    client.save();
    show(client);
}

可以使用像下面这样的query string,来调用该action以创建一个client对象:

?client.name=Zenexity&client.email=contact@zenexity.fr

JPA对象绑定 

我们可以将一个JPA对象与HTTP自动绑定起来。

我们可以在HTTP参数中提供 user.id 字段。当Play发现这个字段时,它会先到数据库中取出相应的实例,然后把HTTP请求中其它的参数赋过去。所以我们可以直接save它。

public static void save(User user) {
    user.save(); // ok with 1.0.1
}

我们可以使用同样的方式来更新完整的对象图,但是必须对每一个子对象提供ID

结果的返回

返回模板:

    render(…)    自动以控制器和操作名称解析默认模板路径

将数据添加到模板范围(域)1.普通方法

通常模板需要数据。可以使用renderArgs对象将这些数据添加到模板范围:

public class Clients extends Controller {
 
    public static void show(Long id) {
        Client client = Client.findById(id);
        renderArgs.put("client", client);
        render();    
    }
}

将数据添加到模板范围(域)2.简单方法

可以使用render(…)方法参数将数据直接传递到模板,这种情况下页面访问的变量名和java变量具有相同的名称。只能以这种方式传递局部变量

指定另一个模板

如果你不想使用默认模板,可以通过在 renderTemplate(…) 中的第一个参数中指定另一个模板名称。例如:

 renderTemplate("Clients/showClient.html", id, client);   

重定向

redirect(…) 方法会产生一个重定向事件,接着会产生一个HTTP Redirect响应。

返回一些文本内容

renderText(…)

返回一个JSON字符串

renderJSON(…)

返回XML字符串

renderXml(…)

方法返回内容类型设置为的XML字符串text/xml。在这里,您可以指定自己的XML字符串,传递org.w3c.dom.Document对象,或传递将由XStream序列化程序序列化的POJO。

返回二进制内容

renderBinary(…) 例如返回图片

下载文件作为附件

您可以设置HTTP标头来指示Web浏览器将二进制响应视为“附件”,通常会导致Web浏览器将文件下载到用户的计算机。为此,将文件名作为参数传递给renderBinary方法,这将使Play设置Content-Disposition响应头,提供文件名。例如,假设User上一个示例中的模型作为一个photoFileName属性:

renderBinary(binaryData, user.photoFileName);

拦截器(Interceptions)

一个controller可以定义多个拦截器方法。拦截器作用于一个controller及其所有子类的所有action方法上。对于定义一些所有action共用的操作时,使用拦截器非常有用,比如:检查用户是否已经登录(有没有访问权),截入request范围内的数据,等等。

这些方法必须是static但不一定是public。您必须使用有效的拦截标记来注释这些方法。

@Before

如果方法上有@Before注解,则它将在该controller中的每一个action被调用前被执行。

@After

使用@After注释注释的方法将在此Controller的每个操作调用后执行。

@Catch

@Catch如果另一个动作方法抛出指定的异常,则会调用注释的方法。抛出的异常作为参数传递给@Catch方法。(就是其他方法抛异常了我来处理)

@Finally

使用@Finally注释的方法总是在对此Controller执行每个操作后执行。

@With注释添加更多拦截器

因为Java不允许多重继承,所以依靠Controller层次结构应用拦截器可能非常有限。但是您可以在完全不同的类中定义一些拦截器,并将它们与使用@With注释的任何控制器进行链接。

会话和Flash范围

如果您必须在多个HTTP请求之间保留数据,则可以将其保存在会话或Flash范围中。存储在会话中的数据在整个用户会话期间可用,并且存储在闪存范围内的数据仅可用于下一个请求。

了解Session和Flash数据不会存储在服务器中,而是使用Cookie机制添加到每个后续HTTP请求中非常重要。因此,数据大小非常有限(最多4 KB),您只能存储String值。

当然,cookie是用密钥签名的,所以客户端不能修改cookie数据(否则会被无效)。播放会话不旨在用作缓存。如果需要缓存与特定会话相关的某些数据,则可以使用Play内置缓存机制,并使用session.getId()键来保持与特定用户会话相关。

例:

public static void index() {
    List messages = Cache.get(session.getId() + "-messages", List.class);
    if(messages == null) {
        // Cache miss
        messages = Message.findByUser(session.get("user"));
        Cache.set(session.getId() + "-messages", messages, "30mn");
    }
    render(messages);
}

关闭Web浏览器时,会话将过期,除非您配置application.session.maxAge

缓存与传统的Servlet HTTP会话对象具有不同的语义。您不能假定这些对象将始终位于缓存中。所以它强制你处理缓存未命中的情况,并保持你的应用程序完全无状态。

© 著作权归作者所有

共有 人打赏支持
星闪
粉丝 0
博文 5
码字总数 5173
作品 0
高级程序员
Play源码深入之七:Play的MVC实现

整体来说,Play1.x是一个较完善的框架,各种功能都一应俱全,有点像句老话“麻雀虽小五脏俱全”哈。虽没有Struts、SpringMVC的大名气,但是使用起来,相当顺手。本文将深入Play1.x的MVC,也整...

刀狂剑痴 ⋅ 2015/08/27 ⋅ 0

PetClinic 学习资料

官方教程 http://docs.spring.io/docs/petclinic.html 1.1 请求控制器 翻译: 下面的这些Bean类,对于请求控制器来说都是可以访问的,并且,它们在petclinic-servlet.xml这个文件里被定义。 ...

对岸 ⋅ 2015/10/19 ⋅ 0

zendFramework——index.php"入口文件的设定"

Zend Framework入口文件的设定 ZendChina资讯:ZF学习中,最让新人头痛的事就是入口文件的设定 index.php (./public/index.php) <?php // 全局处理,主要包括报错级别,时区errorreporting(...

朱树杰 ⋅ 2013/09/30 ⋅ 1

UCC以太网控制器简介

MPC8323E-RDB中QUICC简介 QUICC Engine Block介绍 QUICC Engine Block是一个集成了多种外围设备控制器通信协议的多功能通信综合模块。它提供了片上的系统设计方案,这种方案可以方便芯片能够...

时尚小乌龟 ⋅ 2017/06/09 ⋅ 0

unity 所有碰撞器(触发器),碰撞条件、结果,触发条件、结果。。。以及碰撞函数、触发函数的调用。

要产生碰撞必须为游戏对象添加刚体(Rigidbody)和碰撞器,刚体可以让物体在物理影响下运动。碰撞体是物理组件的一类,它要与刚体一起添加到游戏对象上才能触发碰撞。如果两个刚体相互撞在一...

qq_24378389 ⋅ 2017/03/07 ⋅ 0

play1.2.5公用model层问题

@javadeveloper 你好,想跟你请教个问题:您好,请问下你们是使用的play1.x。我想问下你们多个play项目怎么公用model呢。连接的库是一个库。

八十四亩地 ⋅ 2015/06/23 ⋅ 2

Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试

环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewritemodule modules/modrewrite.so 将其前面的#去掉,如果没有找到则添加...

沧海野狼 ⋅ 2016/09/01 ⋅ 0

Laravel创建第一个程序

1.在使用Laravel 入口文件是在laravle/public/index.php Controller是位于文件laravel/app/Http/Controllers View位于laravel/resources/Views Routes(路由)位于laravel/app/Http文件下。 2.......

小贵子_IOS ⋅ 2016/05/10 ⋅ 0

.Net强类型视图

1.控制器 Controllers/StoreController.cs 2.Models Models/Album.cs 3.视图层 Views/Store/List.cshtml 4.配置命名空间 Views/Web.config 点评,这里的传递要比ViewBag更加方便! 本文转自T...

桃子红了呐 ⋅ 01/07 ⋅ 0

AngularJS(二、如何用AngularJS建立前端代码框架)

首先,我们来看一下工程结构目录: 我们可以看到scripts中分列了一下几个文件夹:controllers、services、directives、filters、vendor,以及两个文件app.js和main.js。 controllers里面主要...

雪飘七月 ⋅ 2015/04/21 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

十五周二次课

十五周二次课 17.1mysql主从介绍 17.2准备工作 17.3配置主 17.4配置从 17.5测试主从同步 17.1mysql主从介绍 MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主...

河图再现 ⋅ 45分钟前 ⋅ 0

docker安装snmp rrdtool环境

以Ubuntu16:04作为基础版本 docker pull ubuntu:16.04 启动一个容器 docker run -d -i -t --name flow_mete ubuntu:16.04 bash 进入容器 docker exec -it flow_mete bash cd ~ 安装基本软件 ......

messud4312 ⋅ 今天 ⋅ 0

OSChina 周一乱弹 —— 快别开心了,你还没有女友呢。

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享吴彤的单曲《好春光》 《好春光》- 吴彤 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :小萝莉街上乱跑,误把我认错成...

小小编辑 ⋅ 今天 ⋅ 7

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部