赞
踩
目录
1、创建Maven工程
2、创建控制层、业务层代码(Controller、Service、自定义注解)、准备SpringMvc核心配置文件
3、准备前端控制器 ,创建一个Servlet,同时在web.xml文件中声明该前端控制器
4、创建Spring容器,通过DOM4J解析springmvc的XML文件
5、扫描springmvc中的控制器以及service类并实例化对象放入容器中
6、实现容器中对象的注入,比如将服务层对象注入至控制层
7、建立请求映射地址与控制器以及方法之间的映射关系
8、接收用户请求并进行分发操作
9、用户请求参数处理
10、控制器方法调用以及不同返回值数据处理
作业:封装用户请求参数
Springmvc核心配置文件:springmvc.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans>
-
- <!-- 配置创建容器时要扫描的包-->
- <component-scan base-package="com.baiqi.controller,com.baiqi.service"></component-scan>
-
- </beans>
web项目核心配置文件:web.xml
- <!DOCTYPE web-app PUBLIC
- "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd" >
-
- <web-app>
- <display-name>Archetype Created Web Application</display-name>
-
-
- <!--配置前端控制器-->
- <servlet>
- <servlet-name>DispatcherServlet</servlet-name>
- <servlet-class>com.springmvc.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:springmvc.xml</param-value>
- </init-param>
- <!--Web服务器一旦启动,Servlet就会实例化创建对象,然后初始化(预备创建对象)-->
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>DispatcherServlet</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- </web-app>
Controller.java
- package cn.huangyan.spring.annotation;
-
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE})
- public @interface Controller {
- String value() default "";
- }
Service.java
- package cn.huangyan.spring.annotation;
-
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE})
- public @interface Service {
- String value() default "";
- }
Autowired.java
- package cn.huangyan.spring.annotation;
-
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Autowired {
- String value() default "";
- }
RequestMapping.java
- package cn.huangyan.spring.annotation;
-
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Documented
- @Retention(RetentionPolicy.RUNTIME) //
- @Target({ElementType.TYPE,ElementType.METHOD})
- public @interface RequestMapping {
- String value() default "";
- }
注意:
- package com.springmvc.servlet;
-
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.springmvc.annotation.Controller;
- import com.springmvc.annotation.RequestMapping;
- import com.springmvc.annotation.ResponseBody;
- import com.springmvc.context.WebApplicationContext;
- import com.springmvc.handler.MyHandler;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
-
- public class DispatcherServlet extends HttpServlet {
-
- //指定SpringMvc容器
- private WebApplicationContext webApplicationContext;
-
- //创建集合 用于存放 映射关系 映射地址 与 控制器.方法,用于发送请求直接从该集合中进行匹配
- List<MyHandler> handList = new ArrayList<>();
-
-
- @Override
- public void init() throws ServletException {
-
- //1、加载初始化参数 classpath:springmvc.xml
- String contextConfigLocation = this.getServletConfig().getInitParameter("contextConfigLocation");
-
- //2、创建Springmvc容器
- webApplicationContext = new WebApplicationContext(contextConfigLocation);
-
- //3、进行初始化操作
- webApplicationContext.onRefresh();
-
- //4、初始化请求映射关系 /findUser ===》控制器.方法
- initHandlerMapping();
- }
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //进行请求分发处理
- doDispatcher(request,response);
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doPost(request,response);
- }
-
- //进行请求分发处理
- public void doDispatcher(HttpServletRequest req, HttpServletResponse resp){
-
- //根据用户的请求地址 /findUser 查找Handler|Controller
- MyHandler myHandler = getHandler(req);
-
- try{
-
- if(myHandler == null){
- resp.getWriter().print("<h1>404 NOT FOUND!</h1>");
- }else{
-
- //调用处理方法之前 进行参数的注入
-
- //调用目标方法
- Object result = myHandler.getMethod().invoke(myHandler.getController());
-
- if(result instanceof String){
- //跳转JSP
- String viewName=(String)result;
- // forward:/success.jsp
- if(viewName.contains(":")){
- String viewType=viewName.split(":")[0];
- String viewPage=viewName.split(":")[1];
- if(viewType.equals("forward")){
- req.getRequestDispatcher(viewPage).forward(req,resp);
- }else{
- // redirect:/user.jsp
- resp.sendRedirect(viewPage);
- }
- }else{
- //默认就转发
- req.getRequestDispatcher(viewName).forward(req,resp);
- }
- }else{
- //返回JSON格式数据
- Method method = myHandler.getMethod();
- if(method.isAnnotationPresent(ResponseBody.class)){
- //将返回值转换成 json格式数据
- ObjectMapper objectMapper = new ObjectMapper();
- String json = objectMapper.writeValueAsString(result);
- resp.setContentType("text/html;charset=utf-8");
- PrintWriter writer = resp.getWriter();
- writer.print(json);
- writer.flush();
- writer.close();
-
- }
- }
-
- }
- }catch(Exception e){
- e.printStackTrace();
- }
-
-
- }
-
- //根据用户请求查找对应的Handler
- /***
- * 获取请求对应的handler
- * @param req
- * @return
- */
- public MyHandler getHandler(HttpServletRequest req) {
- // /findUser
- String requestURI = req.getRequestURI();
- for (MyHandler myHandler : handList) {
- //从容器的Handle取出URL 和 用户的请求地址进行匹配,找到满足条件的Handler
- if (myHandler.getUrl().equals(requestURI)) {
- return myHandler;
- }
- }
- return null;
- }
-
- //初始化请求映射关系
- public void initHandlerMapping(){
-
- for (Map.Entry<String, Object> entry : webApplicationContext.iocMap.entrySet()) {
- //获取bean的class类型
- Class<?> clazz = entry.getValue().getClass();
-
- if(clazz.isAnnotationPresent(Controller.class)){
- //获取bean中所有的方法,为这些方法建立映射关系
- Method[] methods = clazz.getDeclaredMethods();
- for (Method method : methods) {
-
- if(method.isAnnotationPresent(RequestMapping.class)){
- RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
- //获取注解中的值 /findUser
- String url = requestMapping.value();
-
- //建立 映射地址 与 控制器.方法
- MyHandler myHandler = new MyHandler(url,entry.getValue(),method);
- handList.add(myHandler);
- }
- }
-
- }
- }
-
- }
- }
- package com.springmvc.context;
-
- import com.springmvc.annotation.AutoWired;
- import com.springmvc.annotation.Controller;
- import com.springmvc.annotation.Service;
- import com.springmvc.xml.XmlPaser;
-
- import java.io.File;
- import java.lang.reflect.Field;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
-
- /**
- * springMvc容器
- */
- public class WebApplicationContext {
-
- //classpath:springmvc.xml
- String contextConfigLocation;
-
- //定义集合 用于存放 bean 的权限名|包名.类名
- List<String> classNameList = new ArrayList<String>();
-
- //创建Map集合用于扮演IOC容器: key存放bean的名字 value存放bean实例
- public Map<String,Object> iocMap = new ConcurrentHashMap<>();
-
- public WebApplicationContext() {
- }
-
- public WebApplicationContext(String contextConfigLocation) {
- this.contextConfigLocation = contextConfigLocation;
- }
-
- /**
- * 初始化Spring容器
- */
- public void onRefresh(){
-
- //1、进行解析springmvc配置文件操作 ==》 com.baiqi.controller,com.baiqi.service
- String pack = XmlPaser.getbasePackage(contextConfigLocation.split(":")[1]);
-
- String[] packs = pack.split(",");
- //2、进行包扫描
- for(String pa : packs){
- excuteScanPackage(pa);
- }
-
- //3、实例化容器中bean
- executeInstance();
-
- //4、进行 自动注入操作
- executeAutoWired();
- }
-
- //进行自动注入操作
- public void executeAutoWired(){
-
- try {
- //从容器中 取出 bean ,然后判断 bean中是否有属性上使用 AutoWired,如果使用了搞注解,就需要进行自动注入操作
- for (Map.Entry<String, Object> entry : iocMap.entrySet()) {
- //获取容器中的bean
- Object bean = entry.getValue();
- //获取bean中的属性
- Field[] fields = bean.getClass().getDeclaredFields();
- for (Field field : fields) {
- if(field.isAnnotationPresent(AutoWired.class)){
- //获取注解中的value值|该值就是bean的name
- AutoWired autoWiredAno = field.getAnnotation(AutoWired.class);
- String beanName = autoWiredAno.value();
- //取消检查机制
- field.setAccessible(true);
- field.set(bean,iocMap.get(beanName));
-
- }
- }
-
-
- }
- }catch(Exception e){
- e.printStackTrace();
- }
-
- }
-
- /**
- * 实例化容器中的bean
- */
- public void executeInstance(){
-
- try{
- // com.baiqi.controller.UserController com.baiqi.service.impl.UserServiceImpl
- for (String className : classNameList) {
-
- Class<?> clazz = Class.forName(className);
-
- if(clazz.isAnnotationPresent(Controller.class)){
- //控制层 bean
-
- String beanName = clazz.getSimpleName().substring(0,1).toLowerCase()+ clazz.getSimpleName().substring(1);
- iocMap.put(beanName,clazz.newInstance());
-
- }else if(clazz.isAnnotationPresent(Service.class)){
- //Service层 bean
- Service serviceAn = clazz.getAnnotation(Service.class);
- String beanName = serviceAn.value();
- iocMap.put(beanName,clazz.newInstance());
- }
- }
- }catch(Exception e){
- e.printStackTrace();
- }
-
-
- }
-
- /**
- * 扫描包
- */
- public void excuteScanPackage(String pack){
- // com.baiqi.controller ==> com/baiqi/controller
- URL url = this.getClass().getClassLoader().getResource("/" + pack.replaceAll("\\.", "/"));
- String path = url.getFile();
- // /com/bruce/service
- File dir=new File(path);
- for(File f:dir.listFiles()){
- if(f.isDirectory()){
- //当前是一个文件目录 com.baiqi.service.impl
- excuteScanPackage(pack+"."+f.getName());
- }else{
- //文件目录下文件 获取全路径 UserController.class ==> com.baiqi.controller.UserController
- String className=pack+"."+f.getName().replaceAll(".class","");
- classNameList.add(className);
- }
- }
- }
-
- }
URL url = getClass().getClassLoader().getResource(path); // 注意path最前面没有/,path = cn/huangyan/spring
String filePath = url.getFile();
File[] files = new File(filePath).listFiles();
- package com.springmvc.xml;
-
- import org.dom4j.Attribute;
- import org.dom4j.Document;
- import org.dom4j.DocumentException;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
-
- import java.io.InputStream;
-
- /**
- * @BelongsProject: SpringMvc
- * @Description: 解析springmvc.xml
- */
- public class XmlPaser {
-
-
- public static String getbasePackage(String xml){
- try {
- SAXReader saxReader=new SAXReader();
- InputStream inputStream = XmlPaser.class.getClassLoader().getResourceAsStream(xml);
- //XML文档对象
- Document document = saxReader.read(inputStream);
- Element rootElement = document.getRootElement();
- Element componentScan = rootElement.element("component-scan");
- Attribute attribute = componentScan.attribute("base-package");
- String basePackage = attribute.getText();
- return basePackage;
- } catch (DocumentException e) {
- e.printStackTrace();
- } finally {
- }
- return "";
- }
-
- }
用于存储url和处理器的映射关系的基础组件
- package com.springmvc.handler;
-
-
- import java.lang.reflect.Method;
-
- /**
- * @BelongsProject: SpringMvc
- * @Description: TODO
- */
-
- public class MyHandler {
-
- //请求URL地址
- private String url;
-
- //后台控制器
- private Object controller;
-
- //控制器中指定的方法
- private Method method;
-
- public MyHandler() {
- super();
- // TODO Auto-generated constructor stub
- }
-
-
- public MyHandler(String url, Object controller, Method method) {
- super();
- this.url = url;
- this.controller = controller;
- this.method = method;
- }
-
- // 省略getter/setter方法
- }
- 学习如何通过包名,扫描定位到包名下的具体一个个的类文件,并对这些类文件进行解析
- 学习如何通过反射获取字段的注解属性值,并通过反射给bean字段设值值
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。