servlet仿struts参数注入

在struts中可以在action中声明一个成员变量如Game game和Date date,接口访问时可以通过http://xxx.com/xxx/addGameScore?game.gameID=xx&&game.score=10&&date=xxx的方式

直接将参数注入。用servlet模拟struts的参数注入,可以使用一个servlet对应一个接口集,如只创建一个servlet就可以处理所有关于玩家Player相关的接口

代码如下:

创建一个PlayerServlet

 1 /**
 2  * 玩家相关入口
 3  *
 4  */
 5 public class PlayerServlet extends HttpServlet {
 6     private static final long serialVersionUID = -5269133950459049991L;
 7
 8     public PlayerServlet() {
 9         super();
10     }
11
12     public void destroy() {
13         super.destroy();
14     }
15
16     public void doGet(HttpServletRequest request, HttpServletResponse response)
17             throws ServletException, IOException {
18         handleService(request,response);
19     }
20
21     public void doPost(HttpServletRequest request, HttpServletResponse response)
22             throws ServletException, IOException {
23         handleService(request,response);
24     }
25     //提交给servlet的参数中必须包含target参数,值为对应action的public方法
26     //处理业务逻辑
27     private void handleService(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
28         PlayerAction playerAction = new PlayerAction();
29         ServletUtil.handleServletRequest(playerAction, request, response);
30         playerAction = null;
31     }
32
33     public void init() throws ServletException {
34
35     }
36 }

如struts一样,需要一个PlayerAction,里面的成员变量为注入的参数,公共方法为对应的逻辑方法

创建PlayerAction

 1 /**
 2  * 玩家相关Action
 3  */
 4 public class PlayerAction extends BaseAction{
 5
 6     private Integer playerID;
 7
 8     private String playerNickName;
 9
10     private Player player;
11
12     private IPlayerService playerService;
13
14     public PlayerAction(){
15         this.playerService = new PlayerServiceImpl();
16     }
17     /**玩家登陆*/
18     public void playerLogin(){
19         System.out.println("playerAccount:"+player.getPlayerAccount());
20         System.out.println("playerPassword:"+player.getPlayerPassword());
21     }
22     /**查询玩家信息*/
23     public void findPlayer(){
24         try {
25             response.getWriter().write("玩家ID:"+playerID+",昵称:"+playerNickName);
26         } catch (Exception e) {
27             e.printStackTrace();
28         }
29     }
30
31 //===========相关get和set方法======================================
32     public void setPlayerID(Integer playerID) {
33         this.playerID = playerID;
34     }
35
36     public void setPlayerNickName(String playerNickName) {
37         this.playerNickName = playerNickName;
38     }
39
40     public void setPlayer(Player player) {
41         this.player = player;
42     }
43     public Player getPlayer() {
44         return player;
45     }
46 }

核心servletUtil,使用java反射注入参数

  1 /**
  2  * servlet工具类,提供servlet向action自动注入参数的相关工具
  3  *
  4  */
  5 public class ServletUtil {
  6     /**
  7      * 处理servlet请求,完成request、response和其它参数注入
  8      * @param baseAction
  9      * @param request
 10      * @param response
 11      */
 12     @SuppressWarnings({ "unchecked", "rawtypes" })
 13     public static void handleServletRequest(BaseAction baseAction,
 14             HttpServletRequest request,HttpServletResponse response){
 15         try {
 16             //注入request和response
 17             requestAndResponseInject(baseAction, request, response);
 18             Map<String, String[]> argsMap  = request.getParameterMap();//获取提交参数
 19             String targetMethod = request.getParameter("target");//获取调用目标方法名
 20             Iterator<Entry<String, String[]>> iterator= argsMap.entrySet().iterator();
 21             while(iterator.hasNext()){
 22                 Entry<String, String[]> entry = iterator.next();
 23                 String key = entry.getKey();
 24                 if(!key.equals("target")){
 25                     ServletUtil.propertyInject(key,entry.getValue(),baseAction);//注入参数
 26                 }
 27             }
 28             Class actionClass = baseAction.getClass();
 29             Method method = actionClass.getDeclaredMethod(targetMethod);
 30             method.invoke(baseAction);//调用目标方法
 31         } catch (Exception e) {
 32             e.printStackTrace();
 33         }
 34     }
 35
 36     /**
 37      * 向目标action注入request和response对象
 38      * @param target 目标action
 39      * @param request
 40      * @param response
 41      * @throws Exception
 42      */
 43     @SuppressWarnings("rawtypes")
 44     private static void requestAndResponseInject(Object target,
 45             HttpServletRequest request,HttpServletResponse response) throws Exception{
 46         Class actionClass = target.getClass();
 47         Field[] fields = actionClass.getFields();
 48         for(Field f:fields){
 49             if(HttpServletRequest.class.isAssignableFrom(f.getType())){
 50                 f.setAccessible(true);
 51                 f.set(target, request);
 52             }else if(HttpServletResponse.class.isAssignableFrom(f.getType())){
 53                 f.setAccessible(true);
 54                 f.set(target, response);
 55             }
 56         }
 57     }
 58     /**
 59      * 属性注入,支持基本类型、时间和对象,List和Set泛型只支持基本类型
 60      * @param key 属性键
 61      * @param value 值
 62      * @param target 注入目标
 63      * @throws Exception
 64      */
 65     @SuppressWarnings({ "rawtypes", "unchecked" })
 66     public static void propertyInject(String key,String[] value,Object target)throws Exception{
 67         Class actionType = target.getClass();
 68         //非自定义复合对象
 69         if(!key.contains(".")){
 70             Field field = actionType.getDeclaredField(key);
 71             Class fieldType = field.getType();
 72             //获取setXXX方法
 73             Method method=actionType.getDeclaredMethod("set"+key.substring(0, 1).toUpperCase()+key.substring(1),fieldType);
 74             if(List.class.isAssignableFrom(fieldType)){//List泛型
 75                 List<Object> list = new ArrayList<Object>();
 76                 //获取泛型类型
 77                 Type[] argType = ((ParameterizedType)field.getGenericType()).getActualTypeArguments();
 78                 for(int i=0;i<value.length;i++){
 79                     list.add(generateNormalValue((Class)argType[0],value[i]));//填入List
 80                 }
 81                 method.invoke(target,list);//注入List
 82             }else if(Set.class.isAssignableFrom(fieldType)){
 83                 Set<Object> set = new HashSet<Object>();
 84                 Type[] argType = ((ParameterizedType)field.getGenericType()).getActualTypeArguments();
 85                 for(int i=0;i<value.length;i++){
 86                     set.add(generateNormalValue((Class)argType[0],value[i]));
 87                 }
 88                 method.invoke(target,set);
 89             }else{
 90                 method.invoke(target,generateNormalValue(fieldType,value[0]));//基本类型
 91             }
 92         }else{//自定义复合对象属性
 93             generateObjectValue(key,value[0],target);
 94         }
 95     }
 96
 97     /**
 98      * 生成基本类型值
 99      * @param fieldType 字段类型
100      * @param value 值
101      * @return
102      * @throws Exception
103      */
104     @SuppressWarnings({ "rawtypes", "unchecked" })
105     private static Object generateNormalValue(Class fieldType,Object value)throws Exception{
106         //如果为时间类型,转换时间
107         if(Date.class.isAssignableFrom(fieldType)){
108             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
109             Date date = sdf.parse(value.toString());
110             return date;
111         }else{//Integer、String、Long等封装类型
112             //获取单参构造函数
113             Constructor<String> ctor = fieldType.getConstructor(String.class);
114             return ctor.newInstance(value);
115         }
116     }
117
118     /**
119      * 生成自定义对象值
120      * @param key 属性键
121      * @param value 值
122      * @param target 注入目标
123      * @throws Exception
124      */
125     @SuppressWarnings({ "rawtypes", "unchecked" })
126     private static void generateObjectValue(String key,Object value,Object target)throws Exception{
127         String subKey = key;
128         Class targetType = target.getClass();
129         String[] keys = key.split("\\.");//分割键
130         subKey = keys[0];
131         Field field = targetType.getDeclaredField(subKey);
132         Class fieldType = field.getType();
133         //获取setXXX方法
134         Method setMethod=targetType.getDeclaredMethod("set"+subKey.substring(0, 1).toUpperCase()+subKey.substring(1),fieldType);
135         if(keys.length>1){
136             Constructor<String> ctor = fieldType.getConstructor();//获取默认构造函数
137             //获取getXXX方法
138             Method getMethod=targetType.getDeclaredMethod("get"+subKey.substring(0, 1).toUpperCase()+subKey.substring(1));
139             Object subTarget = getMethod.invoke(target);
140             if(null==subTarget){
141                 subTarget = ctor.newInstance();//调用无参构造函数
142             }
143             setMethod.invoke(target, subTarget);//对象注入
144             generateObjectValue((key.split("\\.", 2))[1],value,subTarget);//子属性还是对象,递归注入
145         }else{
146             setMethod.invoke(target,generateNormalValue(fieldType,value));//子属性为基本类型
147         }
148     }
149 }

代码中的BaseAction就是一个普通的类,包含了request和response成员变量和相关的数据输出方法

 1 /**
 2  * action基类,包含request和response信息及数据输出方法
 3  *
 4  */
 5 public class BaseAction {
 6
 7     public HttpServletRequest request;
 8
 9     public HttpServletResponse response;
10 //==数据输出方法==
11 //....
12 }

web.xml

1   <!-- 玩家相关请求入口 -->
2     <servlet-name>PlayerServlet</servlet-name>
3     <servlet-class>com.xxx.servlet.PlayerServlet</servlet-class>
4   </servlet>
5   <servlet-mapping>
6     <servlet-name>PlayerServlet</servlet-name>
7     <url-pattern>/player</url-pattern>
8   </servlet-mapping>

调用方式:

调用登陆方法:http://www.xxx.com/项目根/player?target=playerLogin&player.playerAccount=xx&player.playerPassword=xxx

调用查询方法:http://www.xxx.com/项目根/player?target=findPlayer&player.playerID=xx

本文地址:http://www.cnblogs.com/wangjiajun/p/4788308.html

时间: 2024-10-25 17:39:45

servlet仿struts参数注入的相关文章

struts2 参数注入 方法拦截器

web.xml: <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://java.sun.com/xml/ns/javaee"

看你的门-攻击服务器(4)-HTTP参数注入攻击

首先需要声明.这纯粹是没有远见和有点真才实学开发一个愚蠢的观点,只为web参考系统安全. 1.HTTP参数注入攻击 參数,被用做后端HTTP请求中的參数,这个时候就有可能会导致HTTP參数注入. 一个自己想出来的烂例如: 一个P2P的转账系统:钱(money),从哪里(from)到哪里去(to). 一个非常easy的系统.开发的时候为了复用代码.加了一个推断字符(check).当然,这个推断字符(check)是不会出如今这个P2P的转账系统的文档系统中: 2.一个典型的easy被HTTP參数注入

看好你的门-攻击服务端(4)-HTTP参数注入攻击

首先需要声明,本文纯属一个毫无远见和真才实学的小小开发人员的愚昧见解,仅供用于web系统安全方面的参考. 1.HTTP参数注入攻击 如果用户提交的参数,被用做后端HTTP请求中的参数,这个时候就有可能会导致HTTP参数注入. 一个自己想出来的烂比方: 一个P2P的转账系统:钱(money),从哪里(from)到哪里去(to). 一个很简单的系统.开发的时候为了复用代码,加了一个判断字符(check),当然,这个判断字符(check)是不会出现在这个P2P的转账系统的文档系统中: 2.一个典型的容

Servlet中读取参数的几种方式

为每一Servlet设置初始化参数 可以为每一个Servlet在对应的web.xml中的Servlet节点下编写初始化参数,格式如下: <init-param> <param-name>userName</param-name> <param-value>admin</param-value> </init-param> 然后在servlet中用如下代码获取相应的参数: ServletConfig config = this.getS

Spring 参数注入

一个(类)Bean可能包含多种属性,这些属性怎么配置???  见下: 用People  Dog Cat Tiger  Panda五个类来学习一些常用的=_= 重点在XML <!--基本类型注入--> <bean id="tiger" class="party.infoo.entity.Tiger"> <property name="name" value="Tiger_AA"/> <p

报表性能优化方案之善用参数注入

1. 问题描述 对于多数据集关联报表,当数据很大时报表的展现速度就会很慢,或通过写sql语句又很复杂.为此FineReport提供一种,既可加快报表的展现速度,又不用编写复杂的sql语句的方案.即使用动态参数注入功能. 2. 原理 动态参数注入,是通过注入的值对数据库中的数据进行操作的,只是取对应的数据,所以会提高报表的性能. 3. 示例 新建模板 展现多个关联数据表的数据 SQL语句,ds1:SELECT * FROM [订单] SQL语句,ds2:SELECT * FROM 订单明细 报表样

struts请求参数注入的三种方式

.请求参数的注入 在Struts2框架中,表单的提交的数据会自动注入到与Action对象相对应的属性.它与Spring框架中的IoC的注入原理相同,通过Action对象为属性提供setter方法注入 要求: jsp中表单的name属性与Action中对应的属性的setter方法对应.要注入属性值的Action对象,必须为该属性提供setXXX()方法,因为Struts2的内部实现是按照JavaBean规范中提供的setter方法,自动为属性注入值 所以一般在Action中注入的属性的属性名与表单

关于java Servlet,Struts,springMVC 的线程安全问题

现在主流的java的前端框架有:struts1,struts2,springmvc 还有最根本的servlet; 前些天一个朋友问我这方面的问题,就研究一番: 1.关于struts1: Struts1使用的ActionServlet是单例的,由这一个servlet处理所有.do请求.RequestProcessor也是单例. RequestProcessor的processActionCreate方法: /**   * <p>Return an <code>Action</c

【spring】jdbcTemplate之sql参数注入

demo @Repository("jdbcDao") public class JdbcTemplateDao { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private NamedParameterJdbcTemplate namedTemplate; private final static List<String> names = new ArrayList<String>();