控制器代码书写示例片段

本页面主要展示一些常用的控制器类代码片段,以期能够通过这些案例了解控制器的编写要领

起步

http://127.0.0.1/user/test

// 控制器必须声明在controllers或其子package下,注意controllers后面有个s 
package com.xiaonei.rose.usage.controllers;

// 控制器要以Controller结尾,可不继承或实现其他类或接口 
public class UserController {
    public String test() {
        // 返回@开始的字符串,表示将紧跟@之后的字符串显示在页面上 
        return "@" + new java.util.Date(); 
    }
}

返回一个Velocity页面

http://127.0.0.1/user/velocity

public class UserController {
    public String velocity() { 
        // 返回一个普通字符串,表示要从webapp/views/目录下找第一个以user-velocity.开始的页面 
        // 运行本程序时,请在webapp/views/目录下创建一个名为user-velocity.vm的文件,写上文本字符
        return "user-velocity";
    }
}

返回一个JSP页面

http://127.0.0.1/user/jsp

public class UserController {
    public String jsp() {
    // 在webapp/views/目录下创建user-jsp.jsp的文件即可 (UTF-8的)。
    return "user-jsp"; 
    }
}

在页面渲染业务数据

http://127.0.0.1/user/render

import net.paoding.rose.web.Invocation;

public class UserController {
    public String render(Invocation inv) { 
        // 在vm/jsp中可以使用$now渲染这个值 
        inv.addModel("now", new java.util.Date()); 

        // 在vm/jsp中可以使用$user.id, $user.name渲染user的值
        inv.addModel("user", new User(1, "qieqie.wang"));

        // id=1, name=qieqie.wang 
        return "user-render"; 
    }
}

更改控制器映射

http://127.0.0.1/u/test

import net.paoding.rose.web.annotation.Path;

// 在控制器上标注@Path设置"u",自定义映射规则(默认是/user,现改为/u) 
@Path("u") 
public class UserController {
    public String test() {
        return "@" + new java.util.Date(); 
    }
}

重定向(Redirect)

http://127.0.0.1/user/redirect

public class UserController {
    public String redirect() {
        // 以r:开始表示重定向 
        return "r:/user/test";
        // 或 r:http://127.0.0.1/user/test 
    }
}

转发(Forward)

http://127.0.0.1/user/forward

http://127.0.0.1/user/forward2

public class UserController {
    public String forward() {
        // 大多数情况下,以/开始即是转发(除非存在webapp/user/test文件)
        return "/user/test";
    }

    public String forward2() {
        // a:开始表示转发到同一个控制器的acton方法forward(),更多参数有m:/module:,c:/controller:
        return "a:forward?note=可以带参数";
    }
}

自定义方法映射

http://127.0.0.1/user/list-by-group?groupId=123

public class UserController {
    @Get("list-by-group")
    public String listByGroup(@Param("groupId") String groupId) {
        return "@${groupId}"; 
    }
}

使用正则表达式自定义方法映射

http://127.0.0.1/user/list-by-group-abc

public class UserController {
    @Get("list-by-group-{groupId}") 
    public String listByGroup2(@Param("groupId") int groupId) { 
        return "@string-${groupId}";
    }
}

http://127.0.0.1/user/list-by-group-123

public class UserController {
    @Get("list-by-group-{groupId:\\d+}") 
    public String listByGroup3(@Param("groupId") String groupId) {
        return "@int-${groupId}";
    }
}

有问题?访问 http://127.0.0.1/user/list-by-group-123 打印出"string-123"而非“int-123”? 这是因为listByGroup2和listByGroup3的path定义的"非常一样",Rose自身无法判断哪个优先级更高(对不起,我们还没找到给正则表达式排序的有效方法)。

在此建议如下:

  • 调整path定义:把第二个path改为list-by-group-n{groupId:\d+},然后通过http://127.0.0.1/user/list-by-group-n123 访问它
  • list-by-group-n{groupId} 的优先级高于 list-by-group-{gourpId},Rose先“问”前者,只有前者不能处理时(abc不是数字,所以其不能处理),才走后者
  • 想知道Rose的判断优先顺序?OK,请访问 http://localhost/rose-info/tree
  • 当然,为安全考虑,rose-info/tree这个地址的可访问性,需要您明确把net.paoding.rose.web.controllers.roseInfo.TreeController的DEBUG log级别打开(通过log级别控制权限,算是我们特有的一种思路)

获取request请求参数

http://127.0.0.1/user/param1?name=rose

public String param1(@Param("name") String name) {
    return "@" + name;
}

http://127.0.0.1/user/param2?name=rose

public String param2(Invocation inv) {
    return "@" + inv.getRequest().getParameter("name");
}

http://127.0.0.1/user/param3/rose

@Get("param3/{name}")
public String param3(Invocation inv, @Param("name") String name) {
    // request.getParameter()也能获取@ReqMapping中定义的参数
    return "@method.name=" + name + "; request.param.name=" + inv.getRequest().getParameter("name");
}

数组参数

http://127.0.0.1/usre/array?id=1&id=2&id=3

http://127.0.0.1/usre/array?id=1,2,3,4

public String array(@Param("id") int[] idArray) {
    return "@" + Arrays.toString(idArray);
}

Map参数

http://127.0.0.1/user/keyOfMap?map:1=paoding&map:2=rose

public String keyOfMap(@Param("map") Map<Integer, String> map) {
    return "@" + Arrays.toString(map.keySet().toArray(new int[0]));
}

http://127.0.0.1/user/valuOfMap?map:1=paoding&map:2=rose

public String valueOfMap(@Param("map") Map<Integer, String> map) {
    return "@" + Arrays.toString(map.values().toArray(new String[0]));
}

http://127.0.0.1/user/map?map:1=paoding&map:2=rose

public String map(@Param("map") Map<Integer, String> map) {
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<Integer, String> entry : map.entrySet()) {
        sb.append(entry.getKey()).append("=").append(entry.getValue()).append("<br>");
    }
    return "@" + sb;
}

表单提交

http://127.0.0.1/user?id=1&name=rose

@Post
public String post(User user) {
    return "@" + user.getId() + "=" + user.getName();
}

设置内嵌对象的属性值

POST http://127.0.0.1/user?id=1&name=rose&level.id=3

@Post
public String post(User user) {
    return "@" + user.getId() + "; level.id=" + user.getLevel().getId();
}

返回JSON

http://127.0.0.1/user/json?id=1

http://127.0.0.1/user/json?id=2

public class UserController {
    public Object json(@Param("id") String id) {

        JSONObject json = new JSONObject();

        json.put("id", id);

        json.put("name", "rose");

        json.put("text", "可以有中文");

        // rose将调用json.toString()渲染

        return json;
    }

    // 把JSONObject放到方法中,Rose将帮忙创建实例
    public Object json2(JSONObject json, @Param("id") String id) {

        json.put("id", id);

        json.put("name", "rose");

        json.put("text", "可以有中文");

        // rose将调用json.toString()渲染

        return json;
    }
}

返回XML

http://127.0.0.1/user/xml

public class UserController {
    public Object xml(Invocation inv) {

        User user = new User();

        user.setId(1);

        user.setName("rose");

        inv.addModel("user", user);

        // rose将调用user-xml.xml或.vm或.jsp渲染页面(按字母升序顺序优先: jsp, vm, xml)

        // 使用user-xml.xml的,默认contentType是text/xml;charset=UTF-8,语法同velocity

        // 使用user-xml.jsp或user-xml.vm的可在本方法中标注@HttpFeatures(contentType="xxx")改变

        // jsp的也可通过<%@ page contentType="text/html;charset=UTF-8" %>改变

        return "user-xml";
    }
}

views/user-xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<user>
    <id>$user.id</id>
    <name>$user.name</name>
</user>

如果是使用DOM构建xml的,则建议在所在的controllers下创建DocumentInterceptor拦截器, 控制器直接返回Document对象,

http://127.0.0.1/user/xml2

package com.xiaonei.rose.usage.controllers;

public class DocumentInterceptor extends ControllerInterceptorAdapter {
    @Override
    public Object after(Invocation inv, Object instruction) throws Exception {
        if (instruction instanceof Documenet) {
            Docuement doc = (Docuement) instruction;
            HttpServletResponse response = inv.getResponse();
            if (response.getContentType() == null) {
                response.setContentType("text/xml;charset=UTF-8");
            }
            document.write(response.getWriter());
            return ""; // 返回空串给Rose,让其不用再管render的事情了
        }
        return instruction; 
    }
}
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.DomDocument;
import org.dom4j.Element;

public class UserController {
    public Object xml2(Invocation inv) {
        Document doc = new DomDocument();
        Element listElement = doc.addElement("user-list");
        Element user1Element = listElement.addElement("user");
        user1Element.addAttribute("id", "1");
        user1Element.addAttribute("name", "paoding");
        Element user2Element = listElement.addElement("user");
        user1Element.addAttribute("id", "2");
        user1Element.addAttribute("name", "rose");
        return doc;
    }
}

@IfParamExists

  • @IfParamExists标注在控制器的方法上,表示只有满足@IfParamExists定义的内容才有可能有该方法处理请求。
  • 不同的控制器方法,可以有相同的映射地址和HTTP方法,每个方法上配置不同的@IfParamExists
  • @IfParamExists判断只在地址和HTTP方法已经满足的条件上才进行
  • @IfParamExists("c") 表示只有存在c非空串参数才由该方法处理
  • @IfParamExists("c=:[0-9]+") 表示只有存在c非空串参数,且参数值符合冒号后的正则表达式才由该方法处理
  • @IfParamExists("c=3") 表示只有存在c参数且值为3时才由该方法处理
  • 如果有多个方法符合该规则,则c=3优先级大于c=:[0-9]+,c=:[0-9]+又大于c

参考

Copyright © sobird.me 2017 all right reserved,powered by Gitbook该文件修订时间: 2017-06-13 13:45:56

results matching ""

    No results matching ""