一、先大致了解一下SpringMVC执行流程:
二、直接贴代码,代码中有注释
1.首先创建一个maven web工程 添加如下依赖
4.0.0
com.lh.core
framework
1.0-SNAPSHOT
war
framework Maven Webapp
http://www.leoraqlx.club
UTF-8
1.8
1.8
javax.servlet
javax.servlet-api
3.1.0
org.apache.commons
commons-lang3
3.6
com.alibaba
fastjson
1.2.32
org.projectlombok
lombok
1.16.4
org.jyaml
jyaml
1.3
framework
maven-clean-plugin
3.0.0
maven-resources-plugin
3.0.2
maven-compiler-plugin
3.7.0
maven-surefire-plugin
2.20.1
maven-war-plugin
3.2.0
maven-install-plugin
2.5.2
maven-deploy-plugin
2.8.2
2.编辑web.xml文件
Archetype Created Web Application
dispatchservlet
com.lh.core.framework.servlet.DispatchServlet
dispatchservlet
/*
3.几个需要用到的工具解析类
json解析
package com.lh.core.framework.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* @ProjectName: framework
* @Package: com.lh.core.framework.utils
* @ClassName: JsonUtil
* @Description: 将请求参数转换为jsonobject
* @Author: lihao
* @CreateDate: 2018/11/7 3:36 PM
* @UpdateDate: 2018/11/7 3:36 PM
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
public class JsonUtil {
public static JSONObject getBody(HttpServletRequest request){
String contentType = request.getContentType();
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader=null;
try{
InputStream inputStream = request.getInputStream();
if(inputStream!=null){
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
}else{
stringBuilder.append("");
}
}catch (IOException e) {
e.printStackTrace();
}finally {
if(bufferedReader!=null){
try {
bufferedReader.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
if (contentType.equalsIgnoreCase("application/json")) {
String jsonStr = stringBuilder.toString();
JSONObject jsonObject = JSON.parseObject(jsonStr);
return jsonObject;
}
return null;
}
}
获取Java包下所有的类
package com.lh.core.framework.utils;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* @ProjectName: framework
* @Package: com.lh.core.framework.utils
* @ClassName: PackageUtil
* @Description: 获取Java包下所有的类
* @Author: lihao
* @CreateDate: 2018/10/24 5:41 PM
* @UpdateDate: 2018/10/24 5:41 PM
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
public class PackageUtil {
public static List scanPackage(String packageName){
List classz=new ArrayList<>();
URL url = Thread.currentThread().getContextClassLoader().getResource(packageName.replace(".","/"));
if(url==null){
return null;
}
String pathFile = url.getFile();
File file = new File(pathFile);
String fileList[] = file.list();
for (String path : fileList) {
File eachFile = new File(pathFile + path);
if (eachFile.isDirectory()) {
scanPackage(packageName + "." + eachFile.getName());
} else {
String name = eachFile.getName();
classz.add(packageName + "." +name.substring(0,name.lastIndexOf(".")));
}
}
return classz;
}
}
yml文件解析
package com.lh.core.framework.utils;
import org.ho.yaml.Yaml;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class YmlUtil {
/**
* key:文件名索引
* value:配置文件内容
*/
private static Map ymls = new HashMap<>();
/**
* string:当前线程需要查询的文件名
*/
private static ThreadLocal nowFileName = new ThreadLocal<>();
private static final String PACKAGENAME="spring.application.controller";
private static final String FILENAME="init.yml"; //配置文件名称
/**
* 加载配置文件
* @param fileName
*/
public static void loadYml(String fileName) throws FileNotFoundException {
nowFileName.set(fileName);
if (!ymls.containsKey(fileName)) {
ymls.put(fileName,Yaml.loadType(YmlUtil.class.getResourceAsStream("/" + fileName), LinkedHashMap.class));
}
}
private static Object getValue(String key) throws Exception {
// 首先将key进行拆分
String[] keys = key.split("[.]");
// 将配置文件进行复制
Map ymlInfo = (Map) ymls.get(nowFileName.get()).clone();
for (int i = 0; i < keys.length; i++) {
Object value = ymlInfo.get(keys[i]);
if (i < keys.length - 1) {
ymlInfo = (Map) value;
} else if (value == null) {
throw new Exception("key不存在");
} else {
return value;
}
}
throw new RuntimeException("不可能到这里的...");
}
public static Object getValue() throws Exception {
// 首先加载配置文件
loadYml(FILENAME);
return getValue(PACKAGENAME);
}
}
注解
Controller
package com.lh.core.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @ProjectName: framework
* @Package: com.lh.core.framework
* @ClassName: ControllerAnnotation
* @Description: java类作用描述
* @Author: lihao
* @CreateDate: 2018/10/24 5:05 PM
* @UpdateDate: 2018/10/24 5:05 PM
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Controller {
String value() default "";
}
RequestMapping
package com.lh.core.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @ProjectName: framework
* @Package: com.lh.core.framework.annotation
* @ClassName: RequestMapping
* @Description: java类作用描述
* @Author: lihao
* @CreateDate: 2018/10/24 5:12 PM
* @UpdateDate: 2018/10/24 5:12 PM
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
String value() default "";
}
RequestJson
package com.lh.core.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @ProjectName: framework
* @Package: com.lh.core.framework.annotation
* @ClassName: RequestJson
* @Description: java类作用描述
* @Author: lihao
* @CreateDate: 2018/10/31 5:26 PM
* @UpdateDate: 2018/10/31 5:26 PM
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestJson {
String value() default "";
}
DispatchServlet
package com.lh.core.framework.servlet;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lh.core.framework.annotation.Controller;
import com.lh.core.framework.annotation.RequestJson;
import com.lh.core.framework.annotation.RequestMapping;
import com.lh.core.framework.utils.JsonUtil;
import com.lh.core.framework.utils.PackageUtil;
import com.lh.core.framework.utils.YmlUtil;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class DispatchServlet extends HttpServlet {
Listclassz=new ArrayList<>();//扫描包下所有的类
Map mappingMethodMap=new ConcurrentHashMap<>();//url映射对应的方法
MapmappingClassMap=new ConcurrentHashMap<>();//url映射对应的类
/**
* 初始化,装配接口映射地址
*/
@Override
public void init(){
try {
classz= PackageUtil.scanPackage((String) YmlUtil.getValue());
} catch (Exception e) {
e.printStackTrace();
}
if(classz==null){
return;
}
for (String clazz:classz) {
String mappingUrl="";
try {
Class> loadClass =Class.forName(clazz);
Controller controller = loadClass.getAnnotation(Controller.class);
if(controller==null){
continue;
}
RequestMapping controllerUrl = loadClass.getAnnotation(RequestMapping.class);
mappingUrl=mappingUrl+controllerUrl.value();
Method[] methods = loadClass.getMethods();
for (Method method:methods){
RequestMapping methodMapping = method.getAnnotation(RequestMapping.class);
if(methodMapping==null){
continue;
}
mappingUrl=mappingUrl+methodMapping.value();
mappingMethodMap.put(mappingUrl,method);
}
Object object = loadClass.newInstance();
mappingClassMap.put(mappingUrl,object);
} catch (ClassNotFoundException e) {
e.printStackTrace();
continue;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
/**
* 执行请求,返回结果
* @param request
* @param response
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
String uri = request.getRequestURI();
Method method = mappingMethodMap.get(uri);
Object object = mappingClassMap.get(uri);
if(method==null){
return;
}
JSONObject body =JsonUtil.getBody(request);
Parameter[] parameters = method.getParameters();
Object[] o = buildParam(parameters, body);
try {
Object invoke = method.invoke(object,o);
response.getWriter().write(invoke.toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 封装接口方法的入参
* @param parameters
* @param body
* @return
*/
private Object[] buildParam( Parameter[] parameters, JSONObject body){
Object[] objects=new Object[parameters.length];
for (int i=0;i< parameters.length ;i++) {
RequestJson requestJson = parameters[i].getAnnotation(RequestJson.class);
if(requestJson==null){
continue;
}
Object object = JSON.toJavaObject(body, parameters[i].getType());
objects[i]=object;
}
return objects;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
public void destroy() {
super.destroy();
}
}
自定义一个controller
package com.lh.core.framework.controller;
import com.lh.core.framework.annotation.Controller;
import com.lh.core.framework.annotation.RequestJson;
import com.lh.core.framework.annotation.RequestMapping;
import com.lh.core.framework.request.IndexRequest;
/**
* @ProjectName: framework
* @Package: com.lh.core.framework.controller
* @ClassName: IndexController
* @Description: java类作用描述
* @Author: lihao
* @CreateDate: 2018/11/9 3:04 PM
* @UpdateDate: 2018/11/9 3:04 PM
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
@RequestMapping("/index")
@Controller
public class IndexController {
@RequestMapping("/test")
public String test(@RequestJson IndexRequest request){
System.out.println("request = [" + request + "]");
return "OK";
}
}
请求参数
package com.lh.core.framework.request;
import lombok.Data;
/**
* @ProjectName: framework
* @Package: com.lh.core.framework.request
* @ClassName: IndexRequest
* @Description: java类作用描述
* @Author: lihao
* @CreateDate: 2018/11/9 3:05 PM
* @UpdateDate: 2018/11/9 3:05 PM
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
@Data
public class IndexRequest {
private String title;
private Integer num;
}
源码地址 :https://github.com/lihao95/framework/tree/master/framework