本文爲個人學習筆記,如有錯誤還請大佬指教!🙏
文章目錄
- 編寫流程
- 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>
- 其他頁面