目录
一、自定义框架demo
(一)主要目录结构
(DispatcherServlet
:路径转发,controller
:控制类)
(二)web.xml配置我们的路径
-
web.xml完整代码:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1" metadata-complete="true"> <display-name>Archetype Created Web Application</display-name> <!-- 声明Spring的主配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/*.xml</param-value> </context-param> <!-- 配置Spring的监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 解析乱码 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置SpringMVC后台 .do --> <!-- servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping--> <!-- 配置MyMVC *.do --> <servlet> <servlet-name>mymvc</servlet-name> <servlet-class>com.cungudafa.mymvc.servlet.MyDispatcherServlet</servlet-class> <init-param> <param-name>basePackage</param-name> <param-value>com.cungudafa.mymvc.controller</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>mymvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
-
自定义转发器MyDispatcherServlet.java:
package com.cungudafa.mymvc.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * MyMVC框架的核心Servlet * @author Administrator * */ public class MyDispatcherServlet extends HttpServlet{ @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 { //测试 System.out.println("MyDispatcherServlet doPost……"); } }
(三)主要代码
-
主要目录
运行期间通过动态代理获得接口的代理对象
,这里定义了三个接口:MyController、MyRequestMapping、MyResponseBody
-
1 MyController.java:
package com.cungudafa.mymvc.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Controller注解,定义某个类为控制器 * @author Administrator * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MyController { }
2 MyRequestMapping.java:
package com.cungudafa.mymvc.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * RequestMapping注解,映射请求到某个类/方法 * @author Administrator * */ @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MyRequestMapping { public String value(); }
3 MyResponseBody.java
package com.cungudafa.mymvc.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * RequestMapping注解,映射请求到某个类/方法 * @author Administrator * */ @Target({ElementType.TYPE_PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MyResponseBody { public String value(); }
(四)测试结果
1、在之前的基础上任意输入一个 .do : http://localhost:8080/SpingMVC01/files.do
2、控制台返回
配置成功!
二、JavaSE 高级部分之注解
(一)什么是注解(Annotation )?
Annotation :注解、标释Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 JDK5 开始添加到 Java 的。
(二) 常见注解
(1)java类常用注解
(2)Sping中最常用注解
常用注解Part1:
@Controller & @RequestMapping
- @Controller : 获得类名、方法名
- @RequestMapping :获得参数
-》 下面用一个test示例演示以上两个注解功能:
-》 定义一个father类和一个son类,写main函数测试结果如下:
通过controller可以获得son中里面包含的类名以及方法名
等
通过son中定义的@RequestMapping(value="/xxxxxxxxxx")
可以获得value
值
常用注解Part2:
@Retention&@Target&@Inherited
- @Retention : 元注解 --生命周期在运行时
- @Target :注解可以用在类/接口,方法、字段上
- @Inherited :子类继承注解
-》 下面用一个myannotation示例演示以上三种功能:
-》 在public @interface MyAnnotation
接口里定义了三类注解:
-》 定义一个father类和一个son类,写main函数测试结果如下:
(父类:每个元素都引用了MyAnnotation
接口、son类:仅仅继承)
通过@Retention
运行时判断有MyAnnotation标签、@Target
注解可以用在类/接口,方法、字段上
判断@Inherited
子类是否继承注解
(3)Sping框架通用SQLGenerator.java
目的
:获得sql查询语句:
select * from user_info where 1=1 and user_name = 'zhangsan' and user_id = 10001
-》 下面用一个demo示例演示以上三种功能:
-》 在Column
和Table
两个接口里定义了2类注解:
- @Retention : 元注解 --生命周期在运行时
- @Target :注解可以用在类/接口,方法、字段上
-》 定义一个UserInfo类
和一个student类
,写main函数测试结果如下:
(运行时类引用了Table
接口、每个元素与(数据库)这里我们与Column
相联系)
-》 定义SQLGenerator.java
:
- 模拟数据库请求操作时,对sql语句变量的控制
select * from user_info where 1=1 and user_name = 'zhangsan' and user_id = 10001
select * from 表名 where 直接写入条件 and 查询关键词1 = '字符串' and 查询关键词2 = 数字
package com.cungudafa.annotation.demo; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; /** * 生成SQL * @author Administrator * */ public class SQLGenerator { public static String createInsertSql(Object o){ return null;//待补充 } public static String createDeleteSql(Object o){ return null; } public static String createUpdateSql(Object o){ return null; } /** * * @param o->UserInfo(id,name) * @return select * from user_info where user_id = ? and user_name = ?; * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws SecurityException * @throws NoSuchFieldException */ public static String createSelectSql(Object o) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException, SecurityException{ //获取传入对象的运行时类 Class c = o.getClass(); //判断该类是否有@Table注解 if(c.isAnnotationPresent(Table.class)){ String sql = "select * from "; Table t = (Table) c.getAnnotation(Table.class); String tableName = t.value(); sql = sql + tableName + " where 1=1 "; //获取所有的get方法 Method[] methods = c.getDeclaredMethods(); List<Method> getMethods = new ArrayList<>(); for(Method method : methods){ if(method.getName().startsWith("get")){ getMethods.add(method); } } //遍历get方法 for(Method method : getMethods){ Object value = method.invoke(o); if(value != null){ String methodName = method.getName();//getUserId/getUserName System.out.println("methodName = " + methodName); //getUserId-->userId String fieldName = methodName.replaceAll("get", "");//UserId fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);//UserId->userId System.out.println("fieldName = " + fieldName); //获得字段 Field field = c.getDeclaredField(fieldName); System.out.println("field = " + field); //判断字段上是否有Column注解 if(field.isAnnotationPresent(Column.class)){ //获得字段上的Column注解 Column col = field.getAnnotation(Column.class); //获得注解的value值,作为列名 String columnName = col.value(); if(value instanceof Integer){//区分id学号String转int(数据库为int) sql = sql + "and " + columnName + " = " + String.valueOf(value) + " "; }else{ sql = sql + "and " + columnName + " = '" + String.valueOf(value) + "' "; } } } } return sql; }else{ return null; } } }
-》 测试结果:(两张表都可以通用SQLGenerator框架)
sql = select * from user_info where 1=1 and user_name = ‘zhangsan’ and user_id = 10001
sql = select * from t_student where 1=1 and t_stuid = 10002 and t_stuname = ‘李四’ and t_stunumber = ‘102001203103’