手写 springmvc
程序员文章站
2022-07-15 11:21:45
...
手写 springmvc
代码下载 : demo
结果测试:
项目结构
0.pom
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<org.slf4j-version>1.7.9</org.slf4j-version>
<org.logback-version>1.0.1</org.logback-version>
</properties>
<dependencies>
<!-- servlet 3.0 start -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- servlet 3.0 end -->
<!-- loggger start -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<!-- loggger end -->
<!-- json start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.8</version>
</dependency>
<!-- json end -->
</dependencies>
1. AttributeParams
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AttributeParams {
String value() default "";
}
2.
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoWrite {
String value() default "";
}
3.
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
String value() default "";
}
4.
@Target({ ElementType.METHOD,ElementType.PACKAGE,ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
String value() default "";
}
5.
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Service {
String value() default "";
}
6.
@RequestMapping("/users")
@Controller
public class UserController {
@AutoWrite
private UserService userService;
@RequestMapping("/user")
public User user(@AttributeParams("name") String name ){
User user = userService.getUserByName(name);
return user;
}
}
7.
public class User implements Serializable{
private String name;
private String pwd;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
8.
public interface UserService {
public User getUserByName(String name);
}
9.
@Service
public class UserServiceImpl implements UserService{
@Override
public User getUserByName(String name) {
User user = new User();
user.setName(name);
user.setPwd(name +"123");
return user;
}
}
10.
public class DispactherServlet extends HttpServlet{
private static final long serialVersionUID = 3077215544607397824L;
private final Logger log = Logger.getLogger(DispactherServlet.class);
static List<String> packageNames = new ArrayList<String>();
static Map<String, Object> instanceMapping = new ConcurrentHashMap<String, Object>();
static Map<String, ApplicationEntity> haddlerMapping = new ConcurrentHashMap<String, ApplicationEntity>();
@Override
public void init() throws ServletException {
super.init();
String application = this.getInitParameter("contextConfigLocation");
//this.getServletContext().getClass().getResourceAsStream(application);
log.info("=== " +application);
String scanPackage="com.curiousby.baoyou.cn.showandshare.customized.mvc";
//1.获取扫描位置
doScan(scanPackage);
for (String packageName : packageNames) {
System.out.println(""+packageName);
}
//2.实例化 service 和 controller
doInstances();
for (Entry<String,Object> entry : instanceMapping.entrySet()) {
System.out.println(entry.getKey() +" \t " + entry.getValue() );
}
//3. 建立映射关系
doHaddlerMapping();
for (Entry<String,ApplicationEntity> entry : haddlerMapping.entrySet()) {
System.out.println(entry.getKey() +" \t " + entry.getValue() );
}
//4.实现注入
doAop();
//5.
}
private void doAop() {
if (instanceMapping.size() <= 0 ) {
return;
}
for (Map.Entry<String, Object> entry : instanceMapping.entrySet()) {
Field[] declaredFields = entry.getValue().getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
if(field.isAnnotationPresent(AutoWrite.class)){
AutoWrite autoWrite = field.getAnnotation(AutoWrite.class);
String autoWriteName = autoWrite.value();
if(!UtilValidate.isNotEmpty(autoWrite.value())){
autoWriteName =field.getName();
}
autoWriteName = StringUtils.toLowerFirstString(autoWriteName);
field.setAccessible(true);
try {
field.set(entry.getValue(), instanceMapping.get(autoWriteName));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
private void doHaddlerMapping() {
if (instanceMapping.size() <= 0 ) {
return;
}
for (Map.Entry<String, Object> entry : instanceMapping.entrySet()) {
if (entry.getValue().getClass().isAnnotationPresent(Controller.class)) {
String baseUrl = "";
Controller controller = entry.getValue().getClass().getAnnotation(Controller.class);
if(entry.getValue().getClass().isAnnotationPresent(RequestMapping.class)){
RequestMapping requestMapping = (RequestMapping) entry.getValue().getClass().getAnnotation(RequestMapping.class);
baseUrl = requestMapping.value();
}
Method[] methods = entry.getValue().getClass().getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(RequestMapping.class)) {
RequestMapping methodRequestMapping = (RequestMapping) method.getAnnotation(RequestMapping.class);
String url = baseUrl + methodRequestMapping.value();
url = StringUtils.splitMultiPathToSimple("/"+url);
ApplicationEntity entity = new ApplicationEntity();
entity.method = method;
entity.controller = entry.getValue();
haddlerMapping.put(url, entity);
}else {
continue;
}
}
}
}
}
private void doInstances() {
if (packageNames.size() <= 0 ) {
return;
}
for (String packageName : packageNames) {
try {
Class<?> clazz = Class.forName(packageName.replace(".class", "").trim());
String clazzName = clazz.getSimpleName();
if (clazz.isAnnotationPresent(Controller.class)) {
Controller controller = clazz.getAnnotation(Controller.class);
if(UtilValidate.isNotEmpty(controller.value())){
clazzName = controller.value();
}
Object newInstance = clazz.newInstance();
clazzName = StringUtils.toLowerFirstString(clazzName);
instanceMapping.put(clazzName, newInstance);
}else if(clazz.isAnnotationPresent(Service.class)){
Service service = clazz.getAnnotation(Service.class);
Class<?>[] interfaces = clazz.getInterfaces();
if(UtilValidate.isNotEmpty(service.value())){
clazzName = service.value();
}else{
for (Class<?> interfaceObj : interfaces) {
clazzName = interfaceObj.getSimpleName();
Object newInstance = clazz.newInstance();
clazzName = StringUtils.toLowerFirstString(clazzName);
instanceMapping.put(clazzName, newInstance);
}
}
}else{
continue;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
private void doScan(String scanPackage) {
URL url = this.getClass().getClassLoader().getResource("/"+StringUtils.splitPathTransfer(scanPackage));
String path= url.getFile();
for ( String file : new File(path).list()) {
File one = new File(path , file);
if (one.isDirectory()) {
doScan(scanPackage +"."+ one.getName());
}else{
packageNames.add(scanPackage+"."+ one.getName());
}
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
RespEntity result = new RespEntity();
String url = req.getRequestURI();
String context = req.getContextPath();
String path = url.replace(context, "").trim();
ApplicationEntity entity = (ApplicationEntity) haddlerMapping.get(path);
if(null == entity){
result.setCode(RespEnums.RESP_ERROR_NOT_FOUND.getCode());
result.setMsg(RespEnums.RESP_ERROR_NOT_FOUND.getDesc());
result.setTimestamp(System.currentTimeMillis());
out(resp, FastJsonUtils.toJSONString(result));
return;
}
List<Object> bulidParameters = bulidParameters(req,resp,entity);
try {
Object obj = entity.method.invoke( entity.controller,bulidParameters.toArray() );
System.out.println(obj);
result = new RespEntity(obj);
out(resp, FastJsonUtils.toJSONString(result));
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private List<Object> bulidParameters(HttpServletRequest req,
HttpServletResponse resp, ApplicationEntity entity) {
Parameter[] parameters = entity.method.getParameters();
List<Object> values = new ArrayList<Object>();
for (Parameter parameter : parameters) {
if (parameter.getParameterizedType().getTypeName().equals("HttpServletRequest")) {
values.add(req);
}else if (parameter.getParameterizedType().getTypeName().equals("HttpServletResponse")) {
values.add(resp);
}else if(parameter.isAnnotationPresent(AttributeParams.class)){
String paramName = parameter.getAnnotation(AttributeParams.class).value();
if(!UtilValidate.isNotEmpty(paramName)){
paramName = parameter.getName();
}
values.add(req.getParameter(paramName));
}else{
String paramName = parameter.getName();
values.add(req.getParameter(paramName));
}
}
return values;
}
private void out(HttpServletResponse response, String str) {
try {
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
捐助开发者
在兴趣的驱动下,写一个免费
的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(支持支付宝和微信 以及扣扣群),没钱捧个人场,谢谢各位。
个人主页:http://knight-black-bob.iteye.com/
谢谢您的赞助,我会做的更好!
上一篇: SpringMVC手写
下一篇: SpringMVC的九大组件
推荐阅读
-
详解springmvc 中controller与jsp传值
-
IDEA搭建Springboot+SpringMVC+Mybatis+Mysql(详细、易懂)
-
postman+json+springmvc测试批量添加实例
-
设计模式:与SpringMVC底层息息相关的适配器模式
-
使用PyTorch实现MNIST手写体识别代码
-
一些手写JavaScript常用的函数汇总
-
stringbuffer截取字符串的下标(解析springmvc工作流程)
-
jsp 显示springmvc modelmap传递的对象详细介绍
-
springmvc+mybatis 做分页sql 语句实例代码
-
Python(TensorFlow框架)实现手写数字识别系统的方法