自定义简陋版SpringMVC

来源:互联网 发布:玩dnf网络冲突怎么办 编辑:程序博客网 时间:2024/06/05 19:30

这几天在家写了一个简陋版的SpringMVC,先把代码贴出来,有兴趣的同学可以看一下。

首先定义了一个简陋的服务器,其实也就是用了ServerSocket写了一个服务端(更详细的点看这里:创建一个简单的web服务器):

public class HttpServer {    public static void main(String[] args) {        await();    }    private static void await() {        ServerSocket serverSocket = null;        try {            ApplicationContext ac = new ApplicationContext(new HttpServletImpl(), "/com/zkn/fullstacktraining/spring/one/spring-config.properties");            ac.init();            boolean shutDown = false;            //创建一个服务端            serverSocket = new ServerSocket(8005, 1, InetAddress.getByName("127.0.0.1"));            //用线程池处理请求            ExecutorService executorService = new ThreadPoolExecutor(10,                    10, 0L, TimeUnit.SECONDS,                    new LinkedBlockingDeque<>(),                    new ThreadFactoryBuilder().setNameFormat("XX-task-%d").build());            while (!shutDown) {                //接收客户端请求                ProcessSocket processSocket = new ProcessSocket(serverSocket.accept());                executorService.execute(processSocket);            }        } catch (Exception e) {            e.printStackTrace();            System.exit(0);        }    }}
这里用了线程池来处理多个socket连接。
接着我们需要自定义一个Request和Response两个类来处理请求和响应信息。

Request这里存了请求头信息、请求参数信息、请求类型、请求URI等。Request的代码如下:

public class Request {    /**     * 输入流     */    private InputStream inputStream;    /**     * 头文件信息     */    private Map<String, String> headerMap = new HashMap<>();    /**     * 参数信息     */    private Map<String, Object> parameterMap = new HashMap<>();    /**     * 是否被解析过     */    private boolean isParser = false;    /**     * 请求类型     */    private String requestMethod;    /**     * 请求URI     */    private String uri;    public Request(InputStream inputStream) {        this.inputStream = inputStream;    }    /**     * 获取头文件信息     *     * @param key     * @return     */    public String getHeader(String key) {        if (key == null) {            return null;        }        return headerMap.get(key.toLowerCase());    }    /**     * 获取参数的值     *     * @param key     * @return     */    public String getParameterValue(String key) {        Object obj = parameterMap.get(key);        if (obj == null)            return null;        if (obj instanceof List) {            if (!((List) obj).isEmpty()) {                return (String) ((List) obj).get(0);            }            return null;        }        return (String) obj;    }    /**     * 获取多个值     *     * @param key     * @return     */    public List<String> getParameterValues(String key) {        Object obj = parameterMap.get(key);        if (obj == null) {            return null;        }        if (obj instanceof List) {            return (List<String>) obj;        }        return null;    }    /**     * 获取所有的key     *     * @return     */    public Set<String> getParameterNames() {        return parameterMap.keySet();    }    public String getRequestMethod() {        return requestMethod;    }    /**     * 解析请求     */    public void parseRequest() {        if (isParser) {            return;        }        isParser = true;        //这里用了BufferedReader 没有考虑性能问题        BufferedReader lineNumberReader = new BufferedReader(new InputStreamReader(inputStream));        try {            //获取请求行 请求行格式 Method URI 协议            String str = lineNumberReader.readLine();            if (str != null) {                String[] strArray = str.split(" ");                requestMethod = strArray[0];                parseUrl(strArray[1]);            }            String headerStr = null;            String[] strArr = null;            //解析头信息            while ((headerStr = lineNumberReader.readLine()) != null) {                if ("".equals(headerStr)) {                    break;                }                strArr = headerStr.split(":");                if (strArr.length == 2) {                    headerMap.put(strArr[0].toLowerCase(), strArr[1].trim());                }            }            //如果是POST请求            String contentType = null;            if ("POST".equals(requestMethod)) {                //文件上传                if ((contentType = headerMap.get("content-type")) != null && headerMap.get("content-type").startsWith("multipart/form-data")) {                    //解析文件上传                    parseUploadFile(lineNumberReader, contentType);                } else {                    //非文件上传                    String postParameter = "";                    while ((postParameter = lineNumberReader.readLine()) != null) {                        if ("".equals(postParameter)) {                            break;                        }                        wrapperParameterValue(postParameter);                    }                }            }            System.out.println(JSON.toJSONString(parameterMap));        } catch (IOException e) {            e.printStackTrace();        }        System.out.println("执行完了。。。");    }    private void parseUploadFile(BufferedReader lineNumberReader, String contentType) throws IOException {        String str;//文件上传的分割位 这里只处理单个文件的上传        String boundary = contentType.substring(contentType.indexOf("boundary") + "boundary=".length());        //解析消息体        while ((str = lineNumberReader.readLine()) != null) {            //解析结束的标记            do {                //读取boundary中的内容                //读取Content-Disposition                str = lineNumberReader.readLine();                //说明是文件上传                if (str.indexOf("Content-Disposition:") >= 0 && str.indexOf("filename") > 0) {                    str = str.substring("Content-Disposition:".length());                    String[] strs = str.split(";");                    String fileName = strs[strs.length - 1].replace("\"", "").split("=")[1];                    System.out.println("fileName = " + fileName);                    //这一行是Content-Type                    lineNumberReader.readLine();                    //这一行是换行                    lineNumberReader.readLine();                    //正式去读文件的内容                    BufferedWriter bw = null;                    try {                        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("G:\\LearnVideo\\fileLoad" + File.separator + fileName), "UTF-8"));                        while (true) {                            str = lineNumberReader.readLine();                            if (str.startsWith("--" + boundary)) {                                break;                            }                            bw.write(str);                            bw.newLine();                        }                        bw.flush();                    } catch (Exception e) {                    } finally {                        if (bw != null) {                            bw.close();                        }                    }                }                if (str.indexOf("Content-Disposition:") >= 0) {                    str = str.substring("Content-Disposition:".length());                    String[] strs = str.split(";");                    String name = strs[strs.length - 1].replace("\"", "").split("=")[1];                    lineNumberReader.readLine();                    StringBuilder stringBuilder = new StringBuilder();                    while (true) {                        str = lineNumberReader.readLine();                        if (str.startsWith("--" + boundary)) {                            break;                        }                        stringBuilder.append(str);                    }                    parameterMap.put(name, stringBuilder.toString());                }            } while (("--" + boundary).equals(str));            //解析结束            if (str.equals("--" + boundary + "--")) {                break;            }        }    }    /**     * 解析URI     *     * @param s     */    private void parseUrl(String s) {        if ("/".equals(s)) {            uri = "/";            return;        }        String tempStr = s;        /**         * 说明可能带参数         */        int flag = 0;        if ((flag = tempStr.indexOf("?")) > 0) {            uri = tempStr.substring(0, flag);            if (tempStr.length() > (flag + 1)) {                tempStr = tempStr.substring(flag + 1, tempStr.length());                String[] strArray = tempStr.split("&");                for (String str : strArray) {                    wrapperParameterValue(str);                }            }            return;        }        uri = s;    }    /**     * 组装参数值     *     * @param str     */    private void wrapperParameterValue(String str) {        Object value;        String[] strArr = str.split("=");        if (strArr.length == 2) {            value = parameterMap.get(strArr[0]);            if (value == null) {                parameterMap.put(strArr[0], strArr[1]);            } else {                if (value instanceof List) {                    ((List) value).add(strArr[1]);                } else {                    List<String> list = new ArrayList<>(2);                    list.add((String) value);                    list.add(strArr[1]);                    parameterMap.put(strArr[0], strArr[1]);                }            }        }    }    public String getUri() {        return uri;    }
Response这里只处理了返回简单字符串和返回静态资源文件,Response的代码如下:

public class Response {    /**     * 输出流     */    private OutputStream outputStream;    /**     * 字符输出流     */    private PrintWriter printWriter;    /**     * 请求类     */    private Request request;    /**     * Cookie信息     */    private List<Cookie> cookieList = new ArrayList<>(2);    public Response(OutputStream outputStream, Request request) {        this.outputStream = outputStream;        this.request = request;    }    public void sendStaticResource(String path) {        FileInputStream fis = null;        try {            if ("/".equals(path)) {                path = "/static/html/index.html";            } else {                path = request.getUri();            }            URL url = this.getClass().getResource(path);            if (url != null) {                File file = new File(url.getFile());                if (file.exists() && !file.isDirectory() && file.canRead()) {                    fis = new FileInputStream(file);                    int flag = 0;                    byte[] bytes = new byte[1024];                    while ((flag = fis.read(bytes)) != -1) {                        outputStream.write(bytes, 0, flag);                    }                }            } else {                PrintWriter printWriter = getWriter();                //这里用PrintWriter字符输出流,设置自动刷新                printWriter.write("HTTP/1.1 404 File Not Found \r\n");                printWriter.write("Content-Type: text/html\r\n");                printWriter.write("Content-Length: 23\r\n");                printWriter.write("\r\n");                printWriter.write("<h1>File Not Found</h1>");                printWriter.close();            }        } catch (IOException e) {            e.printStackTrace();        } finally {            if (fis != null) {                try {                    fis.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    public PrintWriter getWriter() throws IOException {        printWriter = new PrintWriter(outputStream, true);        return printWriter;    }    public void sendSuccess() {        PrintWriter printWriter = null;        try {            printWriter = getWriter();            //这里用PrintWriter字符输出流,设置自动刷新            printWriter.write("HTTP/1.1 200 OK \r\n");            printWriter.write("Content-Type: text/html;charset=utf-8\r\n");            printWriter.write("Content-Length: " + "成功了".getBytes().length + "\r\n");            if (cookieList != null && !cookieList.isEmpty()) {                StringBuilder sb = new StringBuilder();                for (int i = 0; i < cookieList.size(); i++) {                    //设置多个Cookie                    sb.append("Set-Cookie: ").append(cookieList.get(i).getKey()).append("=").append(cookieList.get(i).getValue()).append("\r\n");                }                printWriter.write(sb.toString());            }            printWriter.write("\r\n");            printWriter.write("成功了");        } catch (IOException e) {            e.printStackTrace();        } finally {            printWriter.close();        }    }    public void addCookie(Cookie cookie) {        cookieList.add(cookie);    }}
这里我们模仿Servlet,也自定义一个Servlet接口。代码如下:

public interface Servlet {    void init();    void service(Request request, Response response) throws  Exception;    void destory();}
它的一个实现类如下,在这个类中我们根据URI找到对应的请求处理类,并调用响应的请求方法。

public class HttpServletImpl implements Servlet {    private StaticResourceProcessor resouce = new StaticResourceProcessor();    @Override    public void init() {        System.out.println("我被初始化了、、、、、");    }    @Override    public void service(Request request, Response response) throws Exception {        String uri = request.getUri();        if ("/".equals(uri) || (!StringUtils.isEmpty(uri) && uri.startsWith("/static/"))) {            //处理静态资源            resouce.process(request, response);        } else {            RequestMappingInfo mappingInfo = ApplicationContext.mappingMap.get(uri);            if (mappingInfo != null) {                List<String> parameterList = mappingInfo.getParameter();                int parLen = mappingInfo.getParameter().size() - 1;                Class<?>[] clazzs = mappingInfo.getFormalParameter();                List<Object> list = new ArrayList<>();                Object obj = null;                if (clazzs != null) {                    for (int i = 0; i < clazzs.length; i++) {                        obj = getObject(request, response, parameterList, parLen < i, clazzs[i], i);                        list.add(obj);                    }                }                mappingInfo.getMethod().invoke(mappingInfo.getObj(), list.toArray());                response.sendSuccess();            }        }    }    /**     * 组装方法的参数     *     * @param request     * @param response     * @param parameterList     * @param b     * @param clazz     * @param i     * @return     * @throws InstantiationException     * @throws IllegalAccessException     */    private Object getObject(Request request, Response response, List<String> parameterList, boolean b, Class<?> clazz, int i) throws InstantiationException, IllegalAccessException {        Object obj = null;        //如果参数类型为Request        if (clazz.isAssignableFrom(Request.class)) {            obj = request;        } else if (clazz.isAssignableFrom(Response.class)) {            //如果参数类型为Response            obj = response;        }        //如果是字节类型(包含基本类型和包装类)        else if (clazz == byte.class || clazz == Byte.class) {            if (!b) {                obj = Byte.parseByte(request.getParameterValue(parameterList.get(i)));            }        }        //如果是short类型(包含基本类型和包装类)        else if (clazz == short.class || clazz == Short.class) {            if (!b) {                obj = Short.parseShort(request.getParameterValue(parameterList.get(i)));            }        }        //如果是char类型(包含基本类型和包装类)        else if (clazz == char.class || clazz == Character.class) {        }        //如果是整型(包含基本类型和包装类)        else if (clazz == int.class || clazz == Integer.class) {            if (!b) {                obj = Integer.parseInt(request.getParameterValue(parameterList.get(i)));            }        }        //如果是float(包含基本类型和包装类)        else if (clazz == float.class || clazz == Float.class) {            if (!b) {                obj = Float.parseFloat(request.getParameterValue(parameterList.get(i)));            }        }        //如果是double(包含基本类型和包装类)        else if (clazz == double.class || clazz == Double.class) {            if (!b) {                obj = Double.parseDouble(request.getParameterValue(parameterList.get(i)));            }        }        //如果是double(包含基本类型和包装类)        else if (clazz == long.class || clazz == Long.class) {            if (!b) {                obj = Long.parseLong(request.getParameterValue(parameterList.get(i)));            }        }        //如果是boolean(包含基本类型和包装类)        else if (clazz == boolean.class || clazz == Boolean.class) {            if (!b) {                obj = Boolean.parseBoolean(request.getParameterValue(parameterList.get(i)));            }        }        //如果是boolean(包含基本类型和包装类)        else if (clazz == String.class) {            if (!b) {                obj = request.getParameterValue(parameterList.get(i));            }        }        //如果是日期类型,先不做处理        else if (clazz == Date.class) {            obj = new Date();        } else {            //暂不考虑数组、集合、Map等类型            obj = clazz.newInstance();            Field[] fields = obj.getClass().getDeclaredFields();            wrapperObjectFieldValue(request, obj, fields);        }        return obj;    }    /**     * 组装属性对象值     *     * @param request     * @param obj     * @param fields     * @throws IllegalAccessException     */    private void wrapperObjectFieldValue(Request request, Object obj, Field[] fields) throws IllegalAccessException {        if (fields != null) {            Field field = null;            for (int j = 0; j < fields.length; j++) {                field = fields[j];                String fieldName = field.getName();                field.setAccessible(true);                String value = request.getParameterValue(fieldName);                if (value != null && !"".equals(value)) {                    if (field.getType() == byte.class || field.getType() == Byte.class) {                        field.set(obj, Byte.parseByte(value));                    }                    //如果是short类型(包含基本类型和包装类)                    else if (field.getType() == short.class || field.getType() == Short.class) {                        field.set(obj, Short.parseShort(value));                    }                    //如果是char类型(包含基本类型和包装类)                    else if (field.getType() == char.class || field.getType() == Character.class) {                        field.set(obj, value.toCharArray()[0]);                    }                    //如果是整型(包含基本类型和包装类)                    else if (field.getType() == int.class || field.getType() == Integer.class) {                        field.set(obj, Integer.parseInt((value)));                    }                    //如果是float(包含基本类型和包装类)                    else if (field.getType() == float.class || field.getType() == Float.class) {                        field.set(obj, Float.parseFloat((value)));                    }                    //如果是double(包含基本类型和包装类)                    else if (field.getType() == double.class || field.getType() == Double.class) {                        field.set(obj, Double.parseDouble((value)));                    }                    //如果是double(包含基本类型和包装类)                    else if (field.getType() == long.class || field.getType() == Long.class) {                        field.set(obj, Long.parseLong((value)));                    }                    //如果是boolean(包含基本类型和包装类)                    else if (field.getType() == boolean.class || field.getType() == Boolean.class) {                        field.set(obj, Boolean.parseBoolean((value)));                    }                    //如果是boolean(包含基本类型和包装类)                    else if (field.getType() == String.class) {                        field.set(obj, value);                    }                }            }        }    }    @Override    public void destory() {    }}
接着我们模仿Spring写几个注解:

模仿Spring的Autowire注解

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface CustomAutowire {    String name() default "";}
模仿Spring的Component注解:

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface CustomComponent {}
模仿Controller注解:
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface CustomController {}
模仿RequestMapping注解:

@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE,ElementType.METHOD})public @interface CustomRequestMapping {    /**     * URI     * @return     */    String value();    /**     * 参数信息     * @return     */    String[] parameter() default "";}
这里根据请求找到对应的处理类和处理方法的思路是:定义一个Map,key是请求URI,value是自定义的一个类。这个自定义的类(RequestMappingInfo)包含这几个信息:Class信息、Method类、对象、请求参数和方法参数java类在编译为class的时候有release和debug模式之分,在命令行中直接使用javac进行编译的时候,默认的时候release模式,使用release模式会改变形参中的参数名。而IDE都是使用debug模式进行编译的。ant编译的时候,需要在ant的配置文件中指定debug="true"。 如果要修改javac编译类文件的方式的话,需要指定-g参数。即:javac -g 类文件。通常我们都是用IDE进行项目开发的,所以我们的java类在编译成class的时候参数是不会变的,而SpringMVC在处理参数这个地方用到了ASM技术,来获取参数的信息,并且是在第一次处理请求的时候,来获取参数信息并放到缓存中,以后都从缓存中获取参数信息。RequestMappingInfo代码如下:

public class RequestMappingInfo {    /**     * 类名     */    private Class<?> clazz;    /**     * 方法名     */    private Method method;    /**     * 对象     */    private Object obj;    /**     * 参数     */    private List<String> parameter;    /**     * 方法的参数     */    private Class<?>[] formalParameter;//省略get set方法}
接着我们定义一个类方便IOC:

public class BeanDefinitionInfo implements Serializable {    private static final long serialVersionUID = -5988012842492544219L;    /**     * 类信息     */    private Class<?> clazz;    /**     * 对象     */    private Object object;    /**     * 父类     */    private List<Class<?>> superClass;//省略 get set}
接着就是我们比较重要的类了ApplicationContext,我们会在这里类中,简单模仿Spring IOC的过程,扫描固定包下固定注解的类。在这里遇到了一个问题,一开始在加载类的时候自己写了一个类加载器,但是一个类加载器在他的生命周期中只会加载这个类一次,所以会出现多次加载同一个类的情况。后来别人推荐了一个小工具类:Reflections,这个问题才比较完美的解决,Reflections是一个很不错的工具类,可以扫描Classpath下面任意的类,并且让反射更容易。如下:扫描带某个注解的类,获取含有方法名为某个字符串的类等等。github地址在这儿:https://github.com/ronmamo/reflections,里面有很多例子。自定义的ApplicationContext的代码如下:

public class ApplicationContext {    public static final Map<String, RequestMappingInfo> mappingMap = new HashMap<>();    /**     * 所有扫描到的类     */    private static final Map<Class<?>, BeanDefinitionInfo> allScanClazz = new HashMap<>();    private static final List<Class<?>> allClass = Lists.newArrayList();    private static Servlet servlet;    private CustomInputStreamSource streamSource = null;    public ApplicationContext(Servlet servlet, String location) {        this.servlet = servlet;        streamSource = new CustomClasspathResource(location);    }    public void init() throws Exception {        Properties properties = new Properties();        properties.load(streamSource.getInputStream());        String componentScan = properties.getProperty("component.scan");        wrapperCompontent(componentScan);        imitateIOC();        servlet.init();    }    private void wrapperCompontent(String componentScan) throws InstantiationException, IllegalAccessException {        Reflections reflection = new Reflections(componentScan);        //扫描所有有CustomController注解的类        Set<Class<?>> controllerClazz = reflection.getTypesAnnotatedWith(CustomController.class);        //扫描所有有CustomComponent注解的类        Set<Class<?>> componentClazz = reflection.getTypesAnnotatedWith(CustomComponent.class);        //扫描所有有CustomService注解的类        Set<Class<?>> serviceClazz = reflection.getTypesAnnotatedWith(CustomService.class);        for (Iterator<Class<?>> it = controllerClazz.iterator(); it.hasNext(); ) {            wrapperController(it.next());        }        componentClazz.addAll(serviceClazz);        for (Iterator<Class<?>> it = componentClazz.iterator(); it.hasNext(); ) {            Class<?> clazz = it.next();            BeanDefinitionInfo beanDefinitionInfo = new BeanDefinitionInfo();            beanDefinitionInfo.setClazz(clazz);            wrapperSuperClass(clazz, beanDefinitionInfo);            allScanClazz.put(clazz, beanDefinitionInfo);            allClass.add(clazz);        }    }    /**     * 模仿IOC     *     * @throws InstantiationException     * @throws IllegalAccessException     */    private void imitateIOC() throws InstantiationException, IllegalAccessException {        Object instance = null;        BeanDefinitionInfo beanDefinitionInfo = null;        for (Map.Entry<Class<?>, BeanDefinitionInfo> entry : allScanClazz.entrySet()) {            Class clazz = entry.getKey();            beanDefinitionInfo = entry.getValue();            instance = beanDefinitionInfo.getObject();            if (instance == null) {                instance = clazz.newInstance();                beanDefinitionInfo.setObject(instance);            }            Field[] fields = clazz.getDeclaredFields();            if (fields != null && fields.length > 0) {                for (int i = 0; i < fields.length; i++) {                    if (!fields[i].isAccessible()) {                        fields[i].setAccessible(true);                    }                    if (AnnotationUtil.isAutowire(fields[i])) {                        Class tmpClass = fields[i].getType();                        if (tmpClass.isInterface()) {                            BeanDefinitionInfo tmpBean = null;                            for (int j = 0; j < allClass.size(); j++) {                                tmpBean = allScanClazz.get(allClass.get(j));                                if (tmpClass.isAssignableFrom(tmpBean.getClazz())) {                                    if (tmpBean.getObject() == null) {                                        Object tmp = tmpBean.getClazz().newInstance();                                        tmpBean.setObject(tmp);                                    }                                    fields[i].set(instance, tmpBean.getObject());                                    break;                                }                            }                        } else {                            BeanDefinitionInfo tmpBean = allScanClazz.get(tmpClass);                            if (tmpBean.getObject() == null) {                                tmpBean.setObject(tmpBean.getClazz().newInstance());                            }                            fields[i].set(instance, tmpBean.getObject());                        }                    }                }            }        }    }    /**     * 组装Controller     *     * @param clazz     * @throws IllegalAccessException     * @throws InstantiationException     */    private void wrapperController(Class<?> clazz) throws IllegalAccessException, InstantiationException {        Object obj = clazz.newInstance();        BeanDefinitionInfo beanDefinitionInfo = new BeanDefinitionInfo();        beanDefinitionInfo.setClazz(clazz);        beanDefinitionInfo.setObject(obj);        wrapperSuperClass(clazz, beanDefinitionInfo);        allScanClazz.put(clazz, beanDefinitionInfo);        String str = "";        CustomRequestMapping customRequestMapping = null;        if ((customRequestMapping = isRequestMapping(clazz)) != null) {            if (customRequestMapping.value().startsWith("/")) {                str = customRequestMapping.value();            } else {                str = "/" + customRequestMapping.value();            }        }        Method[] methodArray = clazz.getMethods();        if (methodArray != null) {            RequestMappingInfo requestMappingInfo = null;            for (Method method : methodArray) {                customRequestMapping = method.getAnnotation(CustomRequestMapping.class);                if (customRequestMapping != null) {                    requestMappingInfo = new RequestMappingInfo();                    requestMappingInfo.setClazz(clazz);                    requestMappingInfo.setMethod(method);                    requestMappingInfo.setObj(obj);                    Class<?>[] clazzs = method.getParameterTypes();                    String strInner = "";                    if (clazzs != null) {                        requestMappingInfo.setFormalParameter(clazzs);                    }                    if (customRequestMapping.value().startsWith("/")) {                        strInner = customRequestMapping.value();                    } else {                        strInner = "/" + customRequestMapping.value();                    }                    String[] parameter = customRequestMapping.parameter();                    if (parameter != null && parameter.length > 0) {                        requestMappingInfo.setParameter(Arrays.asList(parameter));                    }                    mappingMap.put(str + strInner, requestMappingInfo);                }            }        }    }    /**     * 组装父类     *     * @param clazz     * @param beanDefinitionInfo     */    private void wrapperSuperClass(Class<?> clazz, BeanDefinitionInfo beanDefinitionInfo) {        Class<?> tmp = clazz;        List<Class<?>> superList = Lists.newArrayList();        while (tmp.getSuperclass() != null && tmp.getSuperclass() != Object.class) {            superList.add(clazz.getSuperclass());            tmp = clazz.getSuperclass();        }        beanDefinitionInfo.setSuperClass(superList);    }    public CustomRequestMapping isRequestMapping(Class<?> clazz) {        return clazz.getAnnotation(CustomRequestMapping.class);    }    public static Servlet getServlet() {        return servlet;    }
下面我们写个Controller类来测试一下:

@CustomController@CustomRequestMapping(value = "/custom")public class FirstPageController {    @CustomAutowire    private UserService userService;    @CustomRequestMapping(value = "/myFirstPage.do")    public void myFirstPage() {        System.out.println("我被调用了、、、、");    }    /**     * 插入操作     *     * @param userScope     */    @CustomRequestMapping(value = "/inserUser.do")    public void inserUser(UserScope userScope, Response response) {        Cookie cookie = new Cookie("test", "testcookie");        Cookie cookie2 = new Cookie("test02", "testcookie02");        response.addCookie(cookie);        response.addCookie(cookie2);        System.out.println("我是插入操作的Controller层、、、、");        userService.insert(userScope);    }}
我们在浏览器中输入:http://localhost:8005/custom/myFirstPage.do来看一下结果:

控制台输出如下:



返回结果如下:


和我们程序写的结果一样。

接着我们写一个稍微复杂一点的,定义一个javaBean、DAO类、Service类。
UserScope

public class UserScope implements Serializable{    private static final long serialVersionUID = -8340887359752275426L;    /**     * 用户名     */    private String userName;    /**     * 密码     */    private String passWord;//省略get set}
DAO

public interface UserDAO {    /**     * 插入用户信息     * @param user     * @return     */    Integer insert(UserScope user);}
@CustomComponentpublic class UserDAOImpl implements UserDAO {    private Random random = new Random();    @Override    public Integer insert(UserScope user) {        System.out.println("我是DAO层。。。。进行插入操作......");        System.out.println(JSON.toJSONString(user));        return random.nextInt();    }}
Service:

public interface UserService {    /**     * 插入用户信息     * @param userScope     * @return     */    Integer insert(UserScope userScope);}
@CustomServicepublic class UserServiceImpl implements UserService {    @CustomAutowire    private UserDAO userDAO;    /**     * 插入用户信息     *     * @param userScope     * @return     */    @Override    public Integer insert(UserScope userScope) {        System.out.println("我是Service层。。。。进行插入操作......");        return userDAO.insert(userScope);    }}
从上面的代码中我们可以看到在DAO的实现类上我们用了CustomComponent注解,在Service的实现类上我们用了CustomService的注解。在我们的那个Controller中我们又用了CustomAutowire这个注解。下面我们访问一下看看效果,我们在浏览器中输入:http://localhost:8005/custom/inserUser.do?userName=hangssewe&passWord=2ewewe

控制台输出如下:


浏览器输出为:


我们在Controller中的inserUser这个方法中设置了两个Cookie,我们来看一下Cookie有没有设置成功:


结果和我们预想的是一样的。

接着我们写一个静态资源的处理类:

public class StaticResourceProcessor {    public void process(Request request, Response response) {        response.sendStaticResource(request.getUri());    }}
访问一下看看效果如何:



这里遇到的一个问题是在Chrome浏览器中访问的时候会报错,在IE浏览器中访问则正常显示,还没搞清楚为什么会出现这样的问题。

完整的代码请点击这里:https://github.com/zhangconan/fullstacktraining/tree/master/src/main/java/com/zkn/fullstacktraining/spring/one






原创粉丝点击