前言
- 前段时间写了mvc和mybatis,一直想整合和写一篇博客记录,这次就是记录ssm
- 有兴趣的可以直接看我之前的博客,手写mvc和手写mybatis
- github链接 Beam的ssm
工程目录
代码
引入配置
- pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>myssm</groupId>
<artifactId>myssm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>myssm</name>
<description/>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>bean-validator</artifactId>
<version>3.0-JBoss-4.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.enterprise.deploy</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.jms</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.management.j2ee</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.resource</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.security.auth.message</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.security.jacc</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet.jsp</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api-osgi</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>webservices-api-osgi</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-osgi-bundle</artifactId>
<version>1.0.1-SP3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
<!-- 读取xml文件 -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>${basedir}/WebRoot</warSourceDirectory>
<version>3.0</version>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
添加配置文件
- WEB-INF 下的web.xml修改如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>MySpringMVC</servlet-name>
<servlet-class>com.myssm.config.servlet.MyDispatcherServlet</servlet-class>
<init-param>
<param-name>packagesToScan</param-name>
<param-value>com.myssm.core</param-value>
</init-param>
<init-param>
<param-name>suffix</param-name>
<param-value>.html</param-value>
</init-param>
<init-param>
<param-name>prefix</param-name>
<param-value>html</param-value>
</init-param>
<init-param>
<param-name>mybatisConfigPath</param-name>
<param-value>mybatisconfig/config.xml</param-value>
</init-param>
<init-param>
<param-name>mapperxmlPath</param-name>
<param-value>resources</param-value>
</init-param>
<init-param>
<param-name>mapperPath</param-name>
<param-value>com.myssm.core.mapper</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MySpringMVC</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
- mybatisconfig下的config.xml添加连接数据库的基本信息
<?xml version="1.0" encoding="UTF-8"?>
<database>
<property name="driverClassName">com.mysql.jdbc.Driver</property>
<property name="url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8</property>
<property name="username">root</property>
<property name="password">mimashi0</property>
</database>
注解添加
- 如上注解,有需要的可以直接去我的git上下载看 Beam的ssm
添加mybatis
- 添加Function 类,该类用来接sql方法
package com.myssm.config.mymybatis.config;
public class Function {
private String sqltype; //sql的类型,计划在xml读取有四种情况
private String funcName; // 方法名
private String sql; //执行的sql语句
private Object resultType; // 返回类型
private String parameterType; //参数类型
public String getSqltype() {
return sqltype;
}
public void setSqltype(String sqltype) {
this.sqltype = sqltype;
}
public String getFuncName() {
return funcName;
}
public void setFuncName(String funcName) {
this.funcName = funcName;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public Object getResultType() {
return resultType;
}
public void setResultType(Object resultType) {
this.resultType = resultType;
}
public String getParameterType() {
return parameterType;
}
public void setParameterType(String parameterType) {
this.parameterType = parameterType;
}
}
- 添加MapperBean 类,每一个对应一个mapper.xml,将mapper解析,存入其中
package com.myssm.config.mymybatis.config;
import java.util.List;
public class MapperBean {
private String interfaceName; //接口名
private List<Function> list; //接口下所有方法
public String getInterfaceName() {
return interfaceName;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
public List<Function> getList() {
return list;
}
public void setList(List<Function> list) {
this.list = list;
}
@Override
public String toString() {
return "MapperBean [interfaceName=" + interfaceName + ", list=" + list
+ "]";
}
}
- 添加mybatis的config
package com.myssm.config.mymybatis.config;
public class MybatisConfig {
String configXmlLocation = "";
String mapperPackagePath = "";
public String getConfigXmlLocation(String configXmlLocation) {
System.out.println("configXmlLocation :" + configXmlLocation);
return this.configXmlLocation = this.getClass().getClassLoader().getResource(configXmlLocation).getPath();
}
public String getMapperPackagePath() {
return mapperPackagePath;
}
public void setMapperPackagePath(String mapperPackagePath) {
this.mapperPackagePath = mapperPackagePath;
}
}
- 添加Excutor接口,对应sql语句执行
package com.myssm.config.mymybatis.sqlsession;
import javax.management.Query;
public interface Excutor {
public <T> T query(String statement,Object parameter,Class clzz);
}
- 添加myconfiguration
package com.myssm.config.mymybatis.sqlsession;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.DriverManager;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.myssm.config.mymybatis.config.Function;
import com.myssm.config.mymybatis.config.MapperBean;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class MyConfiguration {
private static ClassLoader loader = ClassLoader.getSystemClassLoader();
public String xmlPath = "";
public String configXmlPath = "";
//读取xml的信息并处理
public Connection build(){
String resource = this.configXmlPath;
try {
// InputStream stream = loader.getResourceAsStream(resource);
InputStream stream = new FileInputStream(resource);
SAXReader reader = new SAXReader();
Document document = reader.read(stream);
Element root = document.getRootElement();
return evalDataSource(root);
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException("error occured while evaling xml " + resource);
}
}
private Connection evalDataSource(Element node) throws ClassNotFoundException {
if(!node.getName().equals("database")){
throw new RuntimeException("没有获取到xml的database根标签");
}
String driverClassName = null;
String url = null;
String username = null;
String password = null;
//遍历跟节点下的全部property标签
for(Object item : node.elements("property")){
Element i = (Element)item;
String value = getValue(i);
String name = i.attributeValue("name");
if(name == null || value == null){
throw new RuntimeException("database标签下的property标签的内容有错");
}
//赋值
switch(name){
case "url" : url = value; break;
case "username" : username = value; break;
case "password" : password = value; break;
case "driverClassName" : driverClassName = value; break;
default : throw new RuntimeException("[database]: <property> unknown name");
}
}
Class.forName(driverClassName);
Connection connection = null;
try {
//建立数据库链接
connection = DriverManager.getConnection(url,username,password);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return connection;
}
//获取property的值,如果有value,则读取,没有设置value,则读取内容
private String getValue(Element node){
return node.hasContent() ? node.getText() : node.attributeValue("value");
}
@SuppressWarnings("rawtypes")
public MapperBean readMapper(){
String path = this.xmlPath;
MapperBean mapper = new MapperBean();
try {
System.out.println("path >>>>> :" + path);
//InputStream stream = loader.getResourceAsStream(path);
InputStream stream = new FileInputStream(path);
SAXReader reader = new SAXReader();
if(stream == null) System.out.println("stream null >>>>>>>>>>>>");
Document document = reader.read(stream);
Element root = document.getRootElement();
mapper.setInterfaceName(root.attributeValue("nameSpace").trim());
List<Function> list = new ArrayList<Function>();//用来存储方法的list
for(Iterator rootIter = root.elementIterator();rootIter.hasNext();) {//遍历根节点下的所有子节点
Function function = new Function(); //用来存储一条方法的记录
Element element = (Element) rootIter.next();
String sqltype = element.getName().trim();
String funcName = element.attributeValue("id").trim();
String sql = element.getText().trim();
String resultType = element.attributeValue("resultType").trim();
function.setSqltype(sqltype);
function.setFuncName(funcName);
Object newInstance = null;
try {
newInstance = Class.forName(resultType).newInstance();
} catch(InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
function.setResultType(newInstance);
function.setSql(sql);
list.add(function);
}
mapper.setList(list);
} catch (DocumentException e) {
// TODO: handle exception
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mapper;
}
public MyConfiguration(String configXmlPath,String xmlPath) {
super();
// TODO Auto-generated constructor stub
this.xmlPath = xmlPath;
this.configXmlPath = configXmlPath;
}
}
- 添加myExcutor 实现Excutor,实现具体的sql语句的执行
package com.myssm.config.mymybatis.sqlsession;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import com.mysql.jdbc.ResultSetMetaData;
import com.myssm.core.pojo.User;
public class MyExcutor implements Excutor{
private MyConfiguration xmlConfiguration ;//= new MyConfiguration("resources/config.xml","resources/UserMapper.xml");
@Override
public <T> T query(String sql, Object parameter,Class clzz) {
// TODO Auto-generated method stub
Connection connection = getConnection();
ResultSet set = null;
PreparedStatement pre = null;
try {
pre = connection.prepareStatement(sql);
//设置参数
pre.setString(1,parameter.toString());
set = pre.executeQuery();
System.out.println("set :" + set.toString());
Object object = clzz.newInstance();
//遍历结果集
ResultSetMetaData metaData = (ResultSetMetaData) set.getMetaData();
while(set.next()){
for (int i = 0; i < metaData.getColumnCount(); i++) {
// resultSet数据下标从1开始
String columnName = metaData.getColumnName(i + 1);
int type = metaData.getColumnType(i + 1);
if (Types.INTEGER == type) {
// int
} else if (Types.VARCHAR == type) {
// String
}
System.out.print(columnName + "\t");
/*u.setId(set.getString(1));
u.setUsername(set.getString(2));
u.setPassword(set.getString(3));*/
Field[] fields = clzz.getDeclaredFields();
for(Field field : fields){
if(field.getName().toLowerCase().equals(columnName.replace("_", ""))){
field.setAccessible(true);
field.set(object,set.getString(i+1));
}
}
}
}
return (T) object;
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
if(set != null){
set.close();
}if(pre != null){
pre.close();
}if(connection != null){
connection.close();
}
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
return null;
}
private Connection getConnection(){
try {
Connection connection = xmlConfiguration.build();
return connection;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
public MyExcutor(MyConfiguration xmlConfiguration) {
super();
// TODO Auto-generated constructor stub
this.xmlConfiguration = xmlConfiguration;
}
}
- 添加mapper的代理类 MyMapperProxy
package com.myssm.config.mymybatis.sqlsession;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
import com.myssm.config.mymybatis.config.Function;
import com.myssm.config.mymybatis.config.MapperBean;
public class MyMapperProxy implements InvocationHandler{
private MySqlsession mySqlsession ;
private MyConfiguration myConfiguration ;
public MyMapperProxy(MyConfiguration myConfiguration,MySqlsession mySqlsession) {
// TODO Auto-generated constructor stub
this.myConfiguration=myConfiguration;
this.mySqlsession=mySqlsession;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
//MapperBean readMapper = myConfiguration.readMapper("resources/UserMapper.xml");
MapperBean readMapper = myConfiguration.readMapper();
//是否是xml文件对应的接口
if(!method.getDeclaringClass().getName().equals(readMapper.getInterfaceName())){
return null;
}
List<Function> list = readMapper.getList();
if(null != list || 0 != list.size()){
for(Function function : list) {
//看id是否和接口的方法名一样
if(method.getName().equals(function.getFuncName())){
return mySqlsession.selectOne(function.getSql(), String.valueOf(args[0]),function.getResultType().getClass());
}
}
}
return null;
}
}
- 添加sqlsession
package com.myssm.config.mymybatis.sqlsession;
import java.lang.reflect.Proxy;
public class MySqlsession {
private Excutor excutor ;
private MyConfiguration myConfiguration ;
public <T> T selectOne(String statement,Object parameter,Class clzz){
return excutor.query(statement, parameter,clzz);
}
@SuppressWarnings("unchecked")
public <T> T getMapper(Class<T> cls){
//动态代理
return (T)Proxy.newProxyInstance(cls.getClassLoader(), new Class[] {cls},
new MyMapperProxy(myConfiguration,this));
}
/*@SuppressWarnings("unchecked")
public <T> T getMapper(){
//动态代理
Class<T> cls = this.clzz;
return (T)Proxy.newProxyInstance(cls.getClassLoader(), new Class[] {cls},
new MyMapperProxy(myConfiguration,this));
}*/
public MySqlsession(Excutor excutor,MyConfiguration myConfiguration) {
super();
// TODO Auto-generated constructor stub
this.excutor = excutor;
this.myConfiguration = myConfiguration;
}
}
配置mvc 并且整合mybatis
- dispatcher
package com.myssm.config.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.net.URL;
import java.security.Policy.Parameters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.logging.Handler;
import javassist.bytecode.SignatureAttribute.MethodSignature;
import javax.activation.FileDataSource;
import javax.ejb.Handle;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.PrefixFileFilter;
import com.alibaba.fastjson.JSONObject;
import com.myssm.config.annotation.MyAutowired;
import com.myssm.config.annotation.MyController;
import com.myssm.config.annotation.MyRequestMapping;
import com.myssm.config.annotation.MyRequestParam;
import com.myssm.config.annotation.MyResponsebody;
import com.myssm.config.annotation.MyService;
import com.myssm.config.mymybatis.sqlsession.MyConfiguration;
import com.myssm.config.mymybatis.sqlsession.MyExcutor;
import com.myssm.config.mymybatis.sqlsession.MySqlsession;
import com.myssm.core.controller.TestController;
import com.myssm.core.mapper.CompanyMapper;
import com.myssm.core.pojo.Company;
import com.myssm.core.pojo.User;
import com.myssm.core.service.UserService;
import com.myssm.core.serviceImpl.UserServiceImpl;
public class MyDispatcherServlet extends HttpServlet{
//放类名
private List<String> classNames = new ArrayList<String>();
//spring的ioc容器
private Map<String, Object> ioc = new HashMap<String, Object>();
//将扫描带有特定注解的方法放在该map中
private Map<String, Method> handlerMapping = new HashMap<String, Method>();
//将扫描带有contoller注解的类放在该map中
private Map<String, Object> controllerMap =new HashMap<String, Object>();
//寻找该项目静态资源时,用户设定的前缀
private String suffix ;
//寻找该项目静态资源时,用户设定的后缀
private String prefix ;
//需要扫描的包名(controllr)
private String packages ;
//mybatis配置路径
private String mybatisConfigPath;
//mybatis的mapperxml的路径
private String mapperxmlPath;
//mapper接口的位置
private String mapperPath;
@Override
public void init(ServletConfig config) throws ServletException {
//1.初始化基本信息
getBasicConfig(config);
//2.初始化所有相关联的类,扫描用户设定的包下面所有的类
scanPackages(this.packages);
//3.拿到扫描到的类,通过反射机制,实例化,并且放到ioc容器中(k-v beanName-bean) beanName默认是首字母小写
doInstance();
doMybatis();
//4.进行依赖注入
doIoc();
//5.初始化HandlerMapping(将url和method对应上)
initHandlerMapping();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//处理请求
doDispatch(req,resp);
} catch (Exception e) {
resp.getWriter().write("500!! Server Exception");
}
}
/* private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
if(handlerMapping.isEmpty()){
return;
}
String url =req.getRequestURI();
String contextPath = req.getContextPath();
url=url.replace(contextPath, "").replaceAll("/+", "/");
System.out.println("dispatcher url :" + url);
if(!this.handlerMapping.containsKey(url)){
resp.getWriter().write("404 NOT FOUND!");
return;
}
Method method =this.handlerMapping.get(url);
//获取方法的参数列表
Class<?>[] parameterTypes = method.getParameterTypes();
//获取请求的参数
Map<String, String[]> parameterMap = req.getParameterMap();
//保存参数值
Object [] paramValues= new Object[parameterTypes.length];
System.out.println(">>>>>>>>>>>>>>>parameterTypes.length :" + parameterTypes.length);
//方法的参数列表
for (int i = 0; i<parameterTypes.length; i++){
//根据参数名称,做某些处理
String requestParam = parameterTypes[i].getSimpleName();
System.out.println(">>>>>>>>>>>>>>>requestParam :" + requestParam);
if (requestParam.equals("HttpServletRequest")){
//参数类型已明确,这边强转类型
paramValues[i]=req;
continue;
}
if (requestParam.equals("HttpServletResponse")){
paramValues[i]=resp;
continue;
}
if(requestParam.equals("String")){
for (Entry<String, String[]> param : parameterMap.entrySet()) {
String value =Arrays.toString(param.getValue()).replaceAll("\\[|\\]", "").replaceAll(",\\s", ",");
paramValues[i]=value;
for(String aString : param.getValue()){
System.out.println("param string[] : " + aString);
}
System.out.println(">>>>>>>>>>>>>>>value :" + value);
}
}
}
//利用反射机制来调用
try {
System.out.println("url :" + url);
System.out.println("object :" + this.controllerMap.get(url));
Object object = method.invoke(this.controllerMap.get(url), paramValues);//第一个参数是method所对应的实例 在ioc容器中
if(method.isAnnotationPresent(MyResponsebody.class)){
if(!(null == object)){
resp.getWriter().write( JSONObject.toJSONString(object) );
}
}else {
Type type = method.getGenericReturnType();
if("class java.lang.String".equals(type.toString())){
outputTheFile(req,resp,object.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}*/
private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
//判断是否url映射的方法是否为空
if(handlerMapping.isEmpty()){
return;
}
String url =req.getRequestURI();
String contextPath = req.getContextPath();
url=url.replace(contextPath, "").replaceAll("/+", "/");
if(!this.handlerMapping.containsKey(url)){
resp.getWriter().write("404 NOT FOUND!");
return;
}
Method method =this.handlerMapping.get(url);
//获取方法的参数列表
Class<?>[] parameterTypes = method.getParameterTypes();
//获取请求的参数
Map<String, String[]> parameterMap = req.getParameterMap();
//保存参数值
Object [] paramValues= new Object[parameterTypes.length];
Parameter[] parameters = method.getParameters();
for (int i = 0; i<parameterTypes.length; i++){
String requestParam = parameterTypes[i].getSimpleName();
if (requestParam.equals("HttpServletRequest")){
//参数类型已明确,这边强转类型
paramValues[i]=req;
System.out.println("request :" + i);
continue;
}
if (requestParam.equals("HttpServletResponse")){
paramValues[i]=resp;
System.out.println("response :" + i);
continue;
}
for(Map.Entry<String, String[]> entry : parameterMap.entrySet()){
if(parameters[i].isAnnotationPresent(MyRequestParam.class)){
String annotationValue = ((MyRequestParam)parameters[i].getAnnotation(MyRequestParam.class)).value();
if(annotationValue.equals(entry.getKey())){
String value =Arrays.toString(entry.getValue()).replaceAll("\\[|\\]", "").replaceAll(",\\s", ",");
paramValues[i] = value;
if(parameters[i].getType().toString().equals("class java.lang.Integer"))
paramValues[i] =Integer.parseInt(value) ;
continue;
}
}
if(parameters[i].getName().equals(entry.getKey())){
String value =Arrays.toString(entry.getValue()).replaceAll("\\[|\\]", "").replaceAll(",\\s", ",");
paramValues[i] = value;
if(parameters[i].getType().toString().equals("class java.lang.Integer"))
paramValues[i] =Integer.parseInt(value) ;
continue;
}
}
}
for(Object prm : paramValues){
}
try {
Object object = method.invoke(this.controllerMap.get(url), paramValues);//第一个参数是method所对应的实例 在ioc容器中
if(method.isAnnotationPresent(MyResponsebody.class)){
if(!(null == object)){
resp.getWriter().write( JSONObject.toJSONString(object) );
}
}else {
Type type = method.getGenericReturnType();
if("class java.lang.String".equals(type.toString())){
outputTheFile(req,resp,object.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void getBasicConfig(ServletConfig config){
this.packages = config.getInitParameter("packagesToScan");
this.suffix = config.getInitParameter("suffix");
this.prefix = config.getInitParameter("prefix");
this.mybatisConfigPath = config.getInitParameter("mybatisConfigPath");
this.mapperxmlPath = config.getInitParameter("mapperxmlPath");
this.mapperPath = config.getInitParameter("mapperPath");
}
private void scanPackages(String packageName) {
//把所有的.替换成/
URL url =this.getClass().getClassLoader().getResource("/"+packageName.replaceAll("\\.", "/"));
File dir = new File(url.getFile());
for (File file : dir.listFiles()) {
if(file.isDirectory()){
//递归读取包
scanPackages(packageName+"."+file.getName());
}else{
String className =packageName +"." +file.getName().replace(".class", "");
classNames.add(className);
}
}
}
private void doInstance() {
if (classNames.isEmpty()) {
return;
}
for (String className : classNames) {
try {
//通过反射机制,将controllr注解和service注解的类获得,放在map上
Class<?> clazz =Class.forName(className);
if(clazz.isAnnotationPresent(MyController.class)){
ioc.put(toLowerFirstWord(clazz.getSimpleName()),clazz.newInstance());
}else if(clazz.isAnnotationPresent(MyService.class)){
String serviceName = clazz.getAnnotation(MyService.class).value();
if(serviceName.equals("") || serviceName == null){
ioc.put(toLowerFirstWord(clazz.getSimpleName()),clazz.newInstance());
}else {
ioc.put(serviceName,clazz.newInstance());
}
}else{
continue;
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
private void initHandlerMapping(){
if(ioc.isEmpty()){
return;
}
try {
for (Entry<String, Object> entry: ioc.entrySet()) {
Class<? extends Object> clazz = entry.getValue().getClass();
if(!clazz.isAnnotationPresent(MyController.class)){
continue;
}
//拼url时,是controller头的url拼上方法上的url
String baseUrl ="";
if(clazz.isAnnotationPresent(MyRequestMapping.class)){
MyRequestMapping annotation = clazz.getAnnotation(MyRequestMapping.class);
baseUrl=annotation.value();
}
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if(!method.isAnnotationPresent(MyRequestMapping.class)){
continue;
}
MyRequestMapping annotation = method.getAnnotation(MyRequestMapping.class);
String url = annotation.value();
url =(baseUrl+"/"+url).replaceAll("/+", "/");
handlerMapping.put(url,method);
controllerMap.put(url,entry.getValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void doIoc(){
if(ioc.isEmpty()) return ;
for(Entry<String, Object> entry : ioc.entrySet()){
Field[] fields = entry.getValue().getClass().getDeclaredFields();
for(Field field : fields){
field.setAccessible(true);
if(field.isAnnotationPresent(MyAutowired.class)){
String autowiredValueName = field.getAnnotation(MyAutowired.class).value();
if(autowiredValueName == null || autowiredValueName.equals("")){
autowiredValueName = toLowerFirstWord(field.getType().getSimpleName());
}
field.setAccessible(true);
try {
field.set(entry.getValue(), ioc.get(autowiredValueName));
} catch (IllegalArgumentException e) {
// TODO: handle exception
e.printStackTrace();
}catch (IllegalAccessException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
}
/*
* 将mapper中的代理类放到ioc中
*/
public void doMybatis(){
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mybatis");
String mybatisConfigPath =this.getClass().getClassLoader().getResource("/"+ this.mybatisConfigPath).getPath();
List<String> mapperxmlList = new ArrayList<String>();
scanMapperXml(mapperxmlList,this.mapperxmlPath);
for(String xmlPath : mapperxmlList){
URL xmlPathUrl =this.getClass().getClassLoader().getResource("/"+ xmlPath);
String className = xmlPath.replace(this.mapperxmlPath + "/", "").replace(".xml", "");
System.out.println(">>> : " + className);
MyConfiguration myConfiguration =new MyConfiguration(mybatisConfigPath,xmlPathUrl.getPath());
MySqlsession sqlsession=new MySqlsession(new MyExcutor(myConfiguration),myConfiguration);
Object mapper = null;
try {
mapper = sqlsession.getMapper(Class.forName(this.mapperPath + "." + className));
ioc.put(toLowerFirstWord(className), mapper);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
}
}
}
/**
* 把字符串的首字母小写
* @param name
* @return
*/
private String toLowerFirstWord(String name){
char[] charArray = name.toCharArray();
charArray[0] += 32;
return String.valueOf(charArray);
}
/**
* 将文件输出到前端
*/
private void outputTheFile(HttpServletRequest request,HttpServletResponse response,
String filePath){
String uri =request.getRequestURI();
String dir = request.getSession(true).getServletContext().getRealPath("/");
dir = dir + prefix + "/" +filePath + suffix;
response.setContentType("text/html; charset=UTF-8");
try {
InputStream inputStream = new FileInputStream(dir);
String html = IOUtils.toString(inputStream,"UTF-8");
PrintWriter out = response.getWriter();
out.println(html);
out.flush();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
//将mapperxml文件全部查询出来
public void scanMapperXml(List<String> mapperXmlList,String path){
//把所有的.替换成/
URL url =this.getClass().getClassLoader().getResource("/"+path.replaceAll("\\.", "/"));
File dir = new File(url.getFile());
for (File file : dir.listFiles()) {
if(file.isDirectory()){
//递归读取包
scanMapperXml(mapperXmlList,path+"/"+file.getName());
}else{
String className =path +"/" +file.getName();
mapperXmlList.add(className);
}
}
}
}
- controller
package com.myssm.core.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.myssm.config.annotation.MyResponsebody;
import com.myssm.core.pojo.User;
import com.myssm.core.service.UserService;
import com.myssm.core.serviceImpl.UserServiceImpl;
import com.myssm.config.annotation.MyAutowired;
import com.myssm.config.annotation.MyController;
import com.myssm.config.annotation.MyRequestMapping;
import com.myssm.config.annotation.MyRequestParam;
@MyController
@MyRequestMapping("/test")
public class TestController {
@MyAutowired
public UserServiceImpl userServiceImpl;
@MyRequestMapping("/string")
//@MyResponsebody
public String stringTest(HttpServletRequest request, HttpServletResponse response){
Map<String, String> map = new HashMap<String, String>();
map.put("123", "454");
return "MyHtml";
}
@MyRequestMapping("/json")
@MyResponsebody
public Map<String, Object> jsonTest(HttpServletRequest request, HttpServletResponse response){
Map<String, Object> map = new HashMap<String, Object>();
map.put("123", "454");
User user = new User();
user.setId("111");
user.setPassword("22");
user.setUsername("33");
map.put("user", user);
return map;
}
@MyRequestMapping("/userservice")
@MyResponsebody
public User userservice(HttpServletRequest request, HttpServletResponse response){
User user = userServiceImpl.getUser();
return user;
}
@MyRequestMapping("param")
@MyResponsebody
public Map paramtest(@MyRequestParam("d")String b,Integer a,Integer c,HttpServletRequest request){
Map<String ,Object> map = new HashMap<String, Object>();
map.put("a", a);
map.put("b", b);
map.put("c", c);
return map;
}
}
- 其余简单的代码就不展示了