可以的,这很RESTful(Spring)

本文介绍了RESTful架构的基本概念及其在SpringMVC中的应用,并通过一个简单的视图控制器类实现RESTful风格的服务端路径控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可以的,这很RESTful

前言

RESTful架构,目前越来越火了,以前很多种URL规定,因他而产生了变化,说不定这也是SpringMVC渐渐取代Struts2的原因之一吧。

REST指的是Representaional State Transfer,表现层状态转化。符合REST原则的架构都可以称为RESTful架构。

其实,简单来说就是你写的每个URL都是一种资源:
比如说:
http://blog.youkuaiyun.com/cjm812752853/article/details/52170611
这个URL就表示http://blog.youkuaiyun.com这个网址下cjm812752853这一个用户的编号为52170611的article的details。

因此,所有很RESTful的框架的URL都是一种资源,所以是名词的URL。那这就有问题了,名词?那具体的操作呢,我怎么知道他要对资源做什么操作,增删改查?

因此,这里又不得不提到一个新的名词,状态转化。状态转化,指的就是客户端和服务端互动的一个过程,客户端向服务端提交的HTTP请求方式,比如说,GET、POST、PUT、DELETE 等等。他表示对资源的四种操作,GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

这就够了。

代码

在对Spring的学习中,我渐渐理解了一些操作的原理,所以我就模仿Spring做了一个小小的视图控制类。
基本思路是这样的,创建一个MyBaseServlet,在这个类中,覆盖他的service方法(public)实现路径的控制,然后子类都要继承这个父类。额是不是很有代码入侵性。
所有代码如下:

MyBaseServlet

package com.chen.util;

import com.chen.annocation.RequestMapping;
import com.chen.enums.RequestMethod;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static javafx.scene.input.KeyCode.R;

/**
 * Created by CHEN on 2016/8/12.
 */
public class MyBaseServlet extends HttpServlet {
    private static final String REDIRECT = "redirect:";
    private static final String FORWARD = "forward:";

    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        String url = req.getRequestURI();
        //获得所有的方法
        //假如没有二级路径或二级以上的路径就会跳到一级路径
        String requestURL = url.substring(url.lastIndexOf("/"));

        if (requestURL == null || "".equals(requestURL)) {
            //假如没有该方法 就要设置一个默认的方法
            requestURL = "";
        }

        try {

/*注释说明:说真的一开始就没打算玩这么大,没打算做那么多个注解,可是,好像上了贼船,只好做了。
            下面这段代码的意思是:找到某个注解,看看他的httpMethod是什么,然后就调用路径的方法,可是这样不够restful.

            //获得请求的http方式
            String httpMethod = req.getMethod();
//            Method[] methods=this.getClass().getMethods(methodStr,HttpServletRequest.class,HttpServletResponse.class);
            Method[] methods = this.getClass().getMethods();
            String returnURL = "/";
            for (Method m : methods) {
                //获得注解的内容
                RequestMapping mapping = m.getDeclaredAnnotation(RequestMapping.class);
                RequestMethod requestMethod = mapping.method();
                if (requestMethod==RequestMethod.valueOf(httpMethod)) {
                    returnURL = (String) m.invoke(this, req, resp);
                    break;
                }
            }*/
            //

            //获得请求的http方式
            String httpMethod = req.getMethod();
            //获得所有的方法
            Method[] methods = this.getClass().getMethods();
            String returnURL = "/";
            for (Method m : methods) {
                //获得注解的内容
                RequestMapping mapping = m.getDeclaredAnnotation(RequestMapping.class);
                //请求http方式
                RequestMethod requestMethod = mapping.method();
                //url路径
                String methodURL=mapping.value();

                if (requestMethod==RequestMethod.valueOf(httpMethod)&&requestURL.equals(methodURL)) {
                    returnURL = (String) m.invoke(this, req, resp);
                    break;
                }
            }


            //重定向
            if (returnURL.startsWith(REDIRECT)) {
                resp.sendRedirect(returnURL.substring(REDIRECT.length()));
                return;
            } else if (returnURL.startsWith(FORWARD)) {
                req.getRequestDispatcher(returnURL.substring(FORWARD.length())).forward(req, resp);
                return;
            } else {
                String rootURL = this.getClass().getResource("/").getPath();
                String realURL = InternalResourceViewResolver.getRealURL(rootURL, returnURL);
                req.getRequestDispatcher(realURL).forward(req, resp);
                return;
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

InternalResourceViewResolver

package com.chen.util;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Iterator;

import static com.sun.deploy.security.ruleset.DRSResult.Type.RUN;


/**
 * Created by CHEN on 2016/8/12.
 * 这是一个视图控制类
 * 主要做的就是从jsp_view.xml中获得路径前缀和后缀
 * 然后拼接,跳转
 */

public class InternalResourceViewResolver {

    public static String getRealURL(String rootURL,String url){
        SAXReader reader = new SAXReader();
        Document document = null;

        try {
            document=reader.read(new  File(rootURL,"jsp_view.xml"));
        } catch (DocumentException e) {
            System.out.println("文件不存在");
            e.printStackTrace();
        }
        if(null==document) {
            //TODO 很多代码
        } else {
            //开始读取xml
            String prefix=null;
            String suffix=null;

            //读取文档
            Element bean =document.getRootElement();
            Iterator<Element> iterator=bean.elementIterator("property");
            Element e=null;
            while(iterator.hasNext()) {
                e= iterator.next();
                if("prefix".equals(e.attributeValue("name"))) {
                    prefix=e.attributeValue("value");
                } else if("suffix".equals(e.attributeValue("name"))) {
                    suffix=e.attributeValue("value");
                }
            }
            StringBuffer string=new StringBuffer(prefix);
            string.append(url);
            string.append(suffix);
            return string.toString();
        }
        return "";
    }

}

RequestMapping

package com.chen.annocation;

import com.chen.enums.RequestMethod;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by CHEN on 2016/8/12.
 * 这是一个注解类,用来注解servlet
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
    RequestMethod method() default RequestMethod.GET;
    String value() default "/";
}

RequestMethod

package com.chen.enums;

/**
 * Created by CHEN on 2016/8/12.
 * http请求方式
 */
public enum RequestMethod {
    GET,HEAD,POST,DELETE,PUT
}

后言

其实这算是一个很简单的Demo了,还缺用户的那些信息之类的,比如说http://blog.youkuaiyun.com/cjm812752853/article/details/52170611中的cjm812752853和52170611还没有实现,但是我觉得,写到这里也就差不多了。
这个用户信息路径值的简单思路应该是这样的(个人想法),把所有的方法value值拿到,然后拿到{}中的请求参数,然后获得相应的值,然后补上去,然后对比。对比一样的,那就是这些方法了。顺带的,可以使用ModelDriven之类的机制构造对象。
如果你有任何疑问,欢迎留言交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值