本文为个人学习笔记,如有错误还请大佬指教!🙏
文章目录
- 编写流程
- 1. 创建普通的JavaWeb工程,并导入相关依赖 与 项目结构预览
- 2. 编写注解类
- 3. 编写配置文件(application.properties)
- 4. 编写HandleMapperInfo.java类,用于存放方法的信息
- 5. 编写HandleRequest.java类处理请求
- 6. 编写HandleResponse.java类处理响应
- 7. 封装判空方法StringUtil.java
- 8. 编写业务层接口与实现类
- 9. 编写控制器 DemoController.java
- 10. 编写HxFrameworkCore.java
- 11. 编写分发器DispatcherServlet.java
- 12. 配置WEB-INF下的web.xml
- 13. 编写网页进行测试
编写流程
- 读取配置文件 得到 需要扫描的基址包路径
- 扫描包,获取类名
- 初始化需要IOC容器管理的类,并将其保存到IOC容器中
- 执行依赖注入,即完成@Autowired
- 构建HandlerMapper,完成URL与Method的关联映射
1. 创建普通的JavaWeb工程,并导入相关依赖 与 项目结构预览
- 导入gson包
2. 编写注解类
- Autowired.java
@Target(ElementType.FIELD) //说明此注解用于字段上
@Retention(RetentionPolicy.RUNTIME) //运行时保留策略
public @interface Autowired {
String value() default "";
}
- Component.java
@Target(ElementType.TYPE) //说明此注解用在类上
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
String value() default "";
}
- Controller.java
@Target(ElementType.TYPE) //此注解用于类上
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
String value() default "";
}
- RequestMapping.java
@Target({ElementType.TYPE,ElementType.METHOD}) //说明此注解用在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
String value() default "";
}
- RequestParam.java
@Target(ElementType.PARAMETER) //说明该注解用在方法的形参上
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestParam {
String value() default "";
}
- ResponseBody.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseBody {
String value() default "";
}
3. 编写配置文件(application.properties)
# 扫描的基址包路径 此行注释,若不支持中文,右键 -> Properties -> Text file encoding -> UTF-8
basePackage=com.hx.spring.mvc
4. 编写HandleMapperInfo.java类,用于存放方法的信息
package com.hx.spring.mvc.core;
import java.lang.reflect.Method;
import java.util.Arrays;
public class HandleMapperInfo {
private Object obj; //方法所属的对象
private Method method; //对应的方法
private Object[] args; //这个方法要的参数
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
@Override
public String toString() {
return "HandleMapperInfo [obj=" + obj + ", method=" + method + ", args=" + Arrays.toString(args) + "]";
}
public HandleMapperInfo(Object obj, Method method) {
super();
this.obj = obj;
this.method = method;
}
public HandleMapperInfo() {
super();
}
}
5. 编写HandleRequest.java类处理请求
package com.hx.spring.mvc.core;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.hx.spring.mvc.core.annotation.RequestParam;
/**
* 处理请求的类
* @author Huathy
* @date 2020年3月12日
*/
public class HandleRequest {
/**
* 处理请求的方法
* @param req
* @param method
* @param resp
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static Object[] handle(HttpServletRequest req,Method method,HttpServletResponse resp) throws InstantiationException, IllegalAccessException{
int count = method.getParameterCount(); //获取这个方法的参数个数
if( count <= 0 ){
return null; //没有参数,无需注值
}
Object[] objs = new Object[count]; //准备存放这个形参所需要的参数
//取出当前方法的形参名
Parameter[] params = method.getParameters(); //获取当前方法的参数
String pname = null; //形参名
RequestParam reqParam; //注解
String paramValue = null; //参数值
String typeName = null; //形参的类型名称
int index = 0; //形参索引下标
Map<String,String[]> paramsMap = null;
Map<String,String> map = null;
Class<?> clazz = null;
Field[] fields = null; //类中的属性
Object instance = null; //对应类的实例化对象
String attrName = null; //属性名
for( Parameter param : params ){
//System.out.println( param.getName() +"\t"+ param.getModifiers() +"\t" + param.getType());
//!!!!!!!这里需要项目右击 complite处做修改!!!!!!!!!
pname = param.getName();
typeName = param.getType().getSimpleName();
//判断此形参是否有@ReuqestParam注解
reqParam = param.getAnnotation(RequestParam.class);
if( reqParam != null ){
pname = reqParam.value(); //有则通过这个里面给定的名称从request中取值
}
//根据参数名,从请求中取值
paramValue = req.getParameter(pname);
if( "Integer".equals(typeName) ){
objs[index] = Integer.valueOf(paramValue);
}else if( "int".equals(typeName) ){
objs[index] = Integer.parseInt(paramValue);
}else if( "Float".equals(typeName) ){
objs[index] = Float.valueOf(paramValue);
}else if( "float".equals(typeName) ){
objs[index] = Float.parseFloat(paramValue);
}else if( "Double".equals(typeName) ){
objs[index] = Double.valueOf(paramValue);
}else if( "double".equals(typeName) ){
objs[index] = Double.parseDouble(paramValue);
}else if( "String".equals(typeName) ){
objs[index] = paramValue;
}else if( "Map".equals(typeName) ){
paramsMap = req.getParameterMap();
map = new HashMap<String, String>();
for( Entry<String,String[]> entry : paramsMap.entrySet() ){
map.put(entry.getKey(), entry.getValue()[0]);
}
objs[index] = map;
}else if( "HttpServletRequest".equals(typeName) || "ServletRequest".equals(typeName) ){
objs[index] = req;
}else if( "HttpServletResponse".equals(typeName) || "ServletResponse".equals(typeName) ){
objs[index] = resp;
}else if( "HttpSession".equals(typeName) ){
objs[index] = req.getSession();
}else if( "ServletContext".equals(typeName) ){
objs[index] = req.getServletContext();
}else{ //当成实体类注值
clazz = param.getType();
fields = clazz.getDeclaredFields(); //获取这个类中的所有属性
instance = clazz.newInstance(); //实例化对象
for(Field fd : fields){ //循环所有属性注值
fd.setAccessible(true); //设置可访问,强问
attrName = fd.getName(); //获取属性的名称
paramValue = req.getParameter(attrName);
typeName = fd.getType().getSimpleName(); //获取属性的类型名称
if(paramValue == null){
continue; //说明这个属性不需要注值
}
//如果不为空,则有需要判断属性的类型
if( "Integer".equals(typeName) ){
fd.set(instance, Integer.valueOf(paramValue));
}else if( "int".equals(typeName) ){
fd.set(instance, Integer.parseInt(paramValue));
}else if( "Float".equals(typeName) ){
fd.set(instance, Float.valueOf(paramValue));
}else if( "float".equals(typeName) ){
fd.set(instance, Float.parseFloat(paramValue));
}else if( "Double".equals(typeName) ){
fd.set(instance, Double.valueOf(paramValue));
}else if( "double".equals(typeName) ){
fd.set(instance, Double.parseDouble(paramValue));
}else {
fd.set(instance, paramValue);
}
}
objs[index] = instance;
}
++ index;
}
return objs;
}
}
6. 编写HandleResponse.java类处理响应
package com.hx.spring.mvc.core;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* 处理响应的类
* @author Huathy
* @date 2020年3月12日
*/
public class HandleResponse {
/**
* 404
* @param resp
* @param url
* @throws IOException
*/
protected static void send404(HttpServletResponse resp ,String url) throws IOException {
PrintWriter out = resp.getWriter();
out.print("<h1>HTTP/1.1 404 File Not Found - "+ url +"</h1>");
out.flush();
}
/**
* 以字节方式返回
* @param resp
* @param bt
* @throws IOException
*/
protected static void sendDate(HttpServletResponse resp ,byte[] bt) throws IOException {
ServletOutputStream sos = resp.getOutputStream();
sos.write(bt);
sos.flush();
}
/**
* 以json格式返回
* @param resp
* @param obj
* @throws IOException
*/
protected static void sendJson(HttpServletResponse resp,Object obj) throws IOException {
PrintWriter out = resp.getWriter();
Gson gson = new GsonBuilder().serializeNulls().create();
out.print( gson.toJson(obj) );
out.flush();
}
}
7. 封装判空方法StringUtil.java
package com.hx.spring.mvc.util;
//由于经常调用封装以下判空方法
public class StringUtil {
//为空判断
public static boolean checkNull(String ... strs){
if(strs == null){
return true;
}
for( String str : strs ){
if(str == null || "".equals(str)){
return true;
}
}
return false;
}
}
8. 编写业务层接口与实现类
- IPersonBiz接口
package com.hx.spring.mvc.biz;
import com.hx.spring.mvc.entity.Person;
public interface IPersonBiz {
public Person findByPid(Integer pid);
}
- 实现类 PersonBizImpl.java
package com.hx.spring.mvc.biz.impl;
import com.hx.spring.mvc.biz.IPersonBiz;
import com.hx.spring.mvc.core.annotation.Autowired;
import com.hx.spring.mvc.core.annotation.Component;
import com.hx.spring.mvc.dao.IPersonDao;
import com.hx.spring.mvc.entity.Person;
@Component
public class PersonBizImpl implements IPersonBiz {
@Autowired
private IPersonDao personDao;
@Override
public Person findByPid(Integer pid) {
return personDao.findByPid(pid);
}
}
9. 编写控制器 DemoController.java
package com.hx.spring.mvc.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import com.hx.spring.mvc.biz.IPersonBiz;
import com.hx.spring.mvc.core.annotation.Autowired;
import com.hx.spring.mvc.core.annotation.Controller;
import com.hx.spring.mvc.core.annotation.RequestMapping;
import com.hx.spring.mvc.core.annotation.RequestParam;
import com.hx.spring.mvc.core.annotation.ResponseBody;
import com.hx.spring.mvc.entity.Person;
@Controller //说明是个控制器
@RequestMapping("/demo")
public class DemoController{
@Autowired
private IPersonBiz personBizImpl;
@RequestMapping("find")
public String find(){
return "redirect:/back/dept.html";
}
@RequestMapping("finds")
public String finds(){
return "/back/emp.html";
}
@RequestMapping("/find1")
public String find1(String ename,Integer age){
System.out.println(ename + "\t" +age);
return "redirect:/back/emp.html";
}
@RequestMapping("/find2")
@ResponseBody //说明以json格式返回数据
public Person find2(String ename,HttpSession session){
Person person = personBizImpl.findByPid(101);
session.setAttribute("person", person);
System.out.println( session.getAttribute("person") );
return person;
}
@RequestMapping("/find3")
@ResponseBody
public List<Person> find3(Person p){
System.out.println(p);
List<Person> list = new ArrayList<>();
list.add( new Person(101,"huathy",18,"123456778") );
list.add( new Person(102,"huasy",20,"123456778") );
list.add( new Person(102,"qq",20,"123456778") );
return list;
}
@RequestMapping("/find4")
public String find4(@RequestParam("name")String ename){
System.out.println(ename);
return "/back/dept.html";
}
@RequestMapping("/find5")
@ResponseBody
public List<Person> find5(Person p, String company){
System.out.println(p);
System.out.println(company);
List<Person> list = new ArrayList<>();
list.add( new Person(101,"huathy",18,"123456778") );
list.add( new Person(102,"huasy",20,"123456778") );
list.add( new Person(102,"qq",20,"123456778") );
return list;
}
@RequestMapping("/find6")
@ResponseBody
public List<Person> find6(Map<String,String> map){
System.out.println(map);
List<Person> list = new ArrayList<>();
list.add( new Person(101,"huathy",18,"123456778") );
list.add( new Person(102,"huasy",20,"123456778") );
list.add( new Person(102,"qq",20,"123456778") );
return list;
}
}
10. 编写HxFrameworkCore.java
package com.hx.spring.mvc.core;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import com.hx.spring.mvc.core.annotation.Autowired;
import com.hx.spring.mvc.core.annotation.Component;
import com.hx.spring.mvc.core.annotation.Controller;
import com.hx.spring.mvc.core.annotation.RequestMapping;
import com.hx.spring.mvc.util.StringUtil;
public class HxFrameworkCore {
private String contextConfigLocation; //配置文件路径
private String basePackage; //要扫描的包的基址路径
private Set<String> classNames = new HashSet<String>(); //扫描到的类路径
private Map<String,Object> instanceObject = new HashMap<String,Object>(); //用来存放实例化后的类
private Map<String,HandleMapperInfo> handleMapper = new HashMap<String,HandleMapperInfo>(); //用来存放url与method的关联映射
public HxFrameworkCore(String contextConfigLocation) {
this.contextConfigLocation = contextConfigLocation;
init();
}
/**
* 初始化方法
*/
private void init() {
//1. 读取配置文件 -> 需要扫描的基址包路径
doLoadConfig();
//2. 扫描包,获取类名
doScannerPackage();
//3. 初始化需要IOC容器管理的类,并将其保存到IOC容器中
doInstanceObject();
//4. 执行依赖注入,即完成@Autowired
doAutowired();
//5. 构建HandlerMapper,完成URL与Method的关联映射
initHandlerMapper();
}
/**
* 1. 读取配置文件 -> 要扫描的包路径
*/
private void doLoadConfig() {
try (InputStream is = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation)){
Properties properties = new Properties();
properties.load(is);
basePackage = properties.getProperty("basePackage");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 2. 扫描包,获取类名
*/
private void doScannerPackage() {
if(StringUtil.checkNull(basePackage)){
throw new RuntimeException("配置文件获取失败,请配置与contextConfigLocation参数!");
}
//System.out.println(basePackage);
URL url = this.getClass().getClassLoader().getResource(basePackage.replaceAll("\\.", "/"));
//System.out.println(url);
File dist = new File(url.getFile());
//System.out.println(dist.getAbsolutePath());
getClassInfo(basePackage,dist);
//System.out.println(classNames);
}
/**
* 获取指定文件夹下的所有文件及其子文件夹中的文件
* @param basePackage
* @param dist
*/
private void getClassInfo(String basePackage, File dist) {
if(dist.isDirectory()){ //判断是否是一个目录
for(File fl : dist.listFiles()){ //循环获取当前文件夹下的文件或子文件夹
if( fl.isDirectory() ){
getClassInfo(basePackage + "." + fl.getName() , fl);
}else{
classNames.add( basePackage + "." + fl.getName().replace(".class", "") ); //获取类名,替换掉“.class”
}
}
}
}
/**
* 3. 初始化需要IOC容器管理的类,并将其保存到IOC容器中
*/
private void doInstanceObject() {
if(classNames.isEmpty()){
return;
}
Class<?> cls = null;
Class<?>[] interfaces = null;
String beanName = null;
String temp;
Object instance = null;
for(String calssName : classNames){
try {
cls = Class.forName(calssName);
beanName = toFirstLowerCase(cls.getSimpleName()); //默认就是将类名第一个字母转为小写
//判断这个类上是否有@Component、@Controller注解,若有则实例化,否则不管
if( cls.isAnnotationPresent(Controller.class) ){ //如果有
temp = cls.getAnnotation(Controller.class).value();
if( !StringUtil.checkNull(temp) ){
beanName = temp;
}
instanceObject.put(beanName, cls.newInstance());
}else if( cls.isAnnotationPresent(Component.class) ){
instance = cls.newInstance();
temp = cls.getAnnotation(Component.class).value();
if( !StringUtil.checkNull(temp) ){
beanName = temp;
}
instanceObject.put(beanName, instance);
//如果这个类上有实现其他接口,为了方便到时候可以将该实现类注入到对应的接口,即可以根据接口注值,我们将实现类与接口名相关联
//到时候可以通过接口名直接找到对应的实现类注入
interfaces = cls.getInterfaces();
for(Class<?> itfs : interfaces){
instanceObject.put(itfs.getSimpleName(), instance);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 将给定的字串第一个字母转为小写
* @param name
* @return
*/
private String toFirstLowerCase(String name){
char[] chs = name.toCharArray();
chs[0] += 32;
return String.valueOf( chs );
}
/**
* 4. 执行依赖注入,即完成@Autowired
*/
private void doAutowired() {
if(instanceObject.isEmpty()){
return;
}
//要获取这个对象中的属,然后看这个属性上有没有@Autowired注解,有才需要处理
Field[] fields = null;
Class<?> cls = null;
Autowired awd = null;
String beanName = null;
for(Entry<String,Object> entry : instanceObject.entrySet()){
cls = entry.getValue().getClass(); //获取当前对象的类信息
fields = cls.getDeclaredFields(); //获取当前类中的所有属性
for( Field fd : fields ){ //喜欢所有属性判断有没有@Autowired注解
if( !fd.isAnnotationPresent(Autowired.class) ){
continue;
}
awd = fd.getAnnotation(Autowired.class); //获取这个注解
beanName = awd.value().trim(); //获取这个注解上配置的名字
//注意:此时所有的属性都是私有的,并且没有给该私有属性提供公有的setter方法,这个时候需要 强吻(强行访问) 即设置可访问
fd.setAccessible(true);
if(!StringUtil.checkNull(beanName)){ //如果指定了注入的bean名称
if(!instanceObject.containsKey(beanName)){ //如果需要注入的这个bean没有交给IOC容器管理
throw new RuntimeException(cls.getName() + "." + fd.getName() + "注值失败,没有对应的实体类" + beanName);
}
try {
fd.set(entry.getValue(), instanceObject.get(beanName));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}else{
//根据类型注值
beanName = fd.getType().getSimpleName(); //获取该字段所属类的类名
try {
fd.set(entry.getValue(), instanceObject.get(beanName));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 5. 构建HandlerMapper,完成URL与Mehtod的关联映射
*/
private void initHandlerMapper() {
if( instanceObject.isEmpty() ){
return;
}
Class<?> cls = null;
String baseUrl = "";
Method[] methods = null;
RequestMapping reqMapper = null;
String url = null;
for(Entry<String,Object> entry : instanceObject.entrySet()){
cls = entry.getValue().getClass(); //获取当前对象的类信息
//判断这个类上有无@Controller注解
if( !cls.isAnnotationPresent(Controller.class) ){
continue;
}
reqMapper = cls.getAnnotation(RequestMapping.class); //判断这个类上是否有@RequestMapping注解
if( reqMapper != null ){ //若不为空,则取出配置
baseUrl = reqMapper.value();
if( !baseUrl.startsWith("/") ){ //说明用户忘记打"/"
baseUrl = "/" +baseUrl;
}
}
//获取这个类中的所有方法
methods = cls.getDeclaredMethods();
if(methods == null || methods.length <= 0){
continue;
}
for( Method method : methods ){ //判断是否有@RequestMapping注解
if( !method.isAnnotationPresent(RequestMapping.class) ){
continue;
}
reqMapper = method.getAnnotation(RequestMapping.class);
url = reqMapper.value();
if(!url.startsWith("/")){ //如果没有打"/"
url = "/" + url;
}
url = baseUrl + url;
handleMapper.put(url.replace("/+", "/"), new HandleMapperInfo(entry.getValue(),method));
}
}
System.out.println(handleMapper);
}
/**
* 根据请求地址获取处理方法
* @param url
* @return
*/
public HandleMapperInfo getMapper(String url){
return handleMapper.getOrDefault(url, null);
}
public Set<String> getClassNames() {
return classNames;
}
public Map<String, Object> getInstanceObject() {
return instanceObject;
}
}
11. 编写分发器DispatcherServlet.java
package com.hx.spring.mvc.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.hx.spring.mvc.core.annotation.ResponseBody;
import com.hx.spring.mvc.util.StringUtil;
public class DispatcherServlet extends HttpServlet{
private static final long serialVersionUID = 4519806829458692203L;
private HxFrameworkCore frameworkCore = null;
@Override
public void init(ServletConfig config){
String configName = "application.properties";
String temp = config.getInitParameter("contextConfigLocation");
if( !StringUtil.checkNull(temp) ){
configName = temp;
}
//读取配置文件,扫描解析注解
frameworkCore = new HxFrameworkCore(configName);
}
@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 {
// 获取请求地址
String url = req.getRequestURI();
// 获取项目名
String contextPath = req.getContextPath();
// 获取请求的资源地址
url = url.replace(contextPath, "").replaceAll("/+", "/"); //处理多余的“/”
if( url.contains("?") ){ //说明请求地址中有带参数
url = url.substring(0, url.indexOf("?"));
}
// 获取有没有处理这个请求的方法
HandleMapperInfo mapperInfo = frameworkCore.getMapper(url);
if(mapperInfo == null){ //说明此路径没有配置对应的处理方法,则先判断是否是静态资源,若也不是,则报错404
handleStaticResource(req.getServletContext().getRealPath("") + url.substring(1), resp);// 当作静态资源处理
return;
}
try {
//若有,则激活此方法,处理这个方法需要的参数,然后获得此方法的返回值
Method method = mapperInfo.getMethod();
//处理这个方法所需参数
Object[] args = HandleRequest.handle(req, method, resp);
Object obj = method.invoke(mapperInfo.getObj(), args);
// 判断这个方法是否以json格式返回
if(method.isAnnotationPresent(ResponseBody.class)){
HandleResponse.sendJson(resp, obj); //以json格式返回
return;
}
if( method.isAnnotationPresent(ResponseBody.class) ){
//说明以json格式返回
}else{
//若没有,则将这个返回对象当作是一个静态资源
String path = String.valueOf(obj);
if( path.startsWith("redirect:") ){ //说明要以重定向方式
path = path.replace("redirect:", "");
if( path.startsWith("/") ){
path = contextPath + path;
}
resp.sendRedirect(path);
return;
}
//否则以内部转发的方法
if( path.startsWith("/") ){
path = contextPath + path;
}
System.out.println(path);
req.getRequestDispatcher(path).forward(req, resp);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
/**
* 处理静态资源的方法
* @param url
* @param resp
* @throws IOException
*/
private void handleStaticResource(String url,HttpServletResponse resp) throws IOException{
File file = new File(url);
if( !file.exists() || !file.isFile() ){
HandleResponse.send404(resp, url);
return;
}
try(FileInputStream fis = new FileInputStream(file)){
byte[] bt = new byte[fis.available()];
fis.read(bt);
HandleResponse.sendDate(resp, bt);
}catch(Exception e){
e.printStackTrace();
}
}
}
12. 配置WEB-INF下的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>200311mySpringMvc</display-name>
<!-- 配置servlet -->
<servlet>
<servlet-name>DispathcherServlet</servlet-name>
<servlet-class>com.hx.spring.mvc.core.DispatcherServlet</servlet-class>
<init-param> <!-- 初始化参数 -->
<param-name>contextConfigLocation</param-name>
<param-value>application.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispathcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
13. 编写网页进行测试
- index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1> <a href="demo/find" target="_blank">find</a> </h1>
<h1> <a href="demo/finds" target="_blank">finds</a> </h1>
<hr/>
<h1> <a href="demo/find1?ename=huathy&age=20" target="_blank">find1</a> </h1>
<h1> <a href="javascript:find2()" >find2</a> </h1>
<h1> <a href="javascript:find3()" >find3</a> </h1>
<h1> <a href="demo/find4?name=huathy" target="_blank">find4</a> </h1>
<hr/>
<h1> <a href="javascript:find5()" >find5</a> </h1>
<h1> <a href="javascript:find6()" >find6</a> </h1>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
function find2(){
$.post("demo/find2",{
name : 'huathy'
},function(data){
console.log(data);
},"json");
}
function find3(){
$.post("demo/find3",{
pid : 101,
pname : 'huathy',
age : 20,
tel : '123456789'
},function(data){
console.log(data);
},"json");
}
function find5(){
$.post("demo/find5",{
pid : 101,
pname : 'huathy',
age : 20,
tel : '123456789',
company : 'huathy科技'
},function(data){
console.log(data);
},"json");
}
function find6(){
$.post("demo/find6",{
pid : 101,
pname : 'huathy',
age : 20,
tel : '123456789'
},function(data){
console.log(data);
},"json");
}
</script>
</body>
</html>
- 其他页面