java web开发框架实例_java web框架

框架结构说明

框架采用MVC模式,Ioc控制反转技术。通过框架来对应用进行初始化和管理,提高开发效率。

若使用传统的Servlet来开发Java Web,Servlet的数量会随着业务功能的扩展而不断增加,系统变得庞大,然以维护,有必要减少Servlet数量,

将某类业务交给Controller来处理,Service负责给Controller提供服务。Service不是通过new方式来创建的,而是通过"依赖注入"的方式,由框架来创建所需要的对象。

框架结构图:

345f7f40adbd23920bf0064d1e1bd1c1.png

DispatherServlet: 请求转发器,通过service()方法转发所有的请求。

Loader: 在DispatherServlet的init()方法调用,进行应用的初始化工作。

ClassHelper:通过ClassUtil类加载应用基础包下所有的类。

BeanContainer:通过BeanFactory将ClassHelper加载获取的所有带有Controller,Service注解等需要容器管理的类进行实例化并保存在容器中。

IocHelper:Controller中定义Service成员变量,需要通过框架自身来实例化。IocHelper将Controller中定义 Service成员变量进行依赖注入。

ControllerHelper:将Controller中带有RequestMapping注解的方法与其要处理的请求路径和请求方法建立映射关系。

创建Maven Web工程 framework-diy,在pom.xml文件引入需要的包。servlet-api,jsp-api,jstl,commons-lang3,commons-collections4,jackson等。

javax.servlet

javax.servlet-api

3.0.1

javax.servlet.jsp

jsp-api

2.2

javax.servlet

jstl

1.2

org.apache.commons

commons-lang3

3.3.2

org.apache.commons

commons-collections4

4.0

com.fasterxml.jackson.core

jackson-databind

2.4.5

加载配置项

首先我们来看下Spring框架,Spring框架定义了一个spring-config.xml配置文件,可以在配置文件定义基础包名,JSP基础路径,静态资源文件的路径等等。

现在我们来仿造一下,为框架定义一个简单的配置文件config.properties(默认配置文件为config.properties),放在/src/main/resources目录下。框架需要根据这些配置项来初始化应用。

//config.properties

#基础包名

app.base_package = com.hubwiz.web

#jsp路径

app.jsp_path = /jsp/

#静态资源路径

app.asset_path = /asset/

有了配置文件,我们需要编写一个PropsUtil类来加载配置文件config.properties。获取当前线程的类加载器,getContextClassLoader().getResourceAsStream(fileName)根据文件名称来加载配置文件。

//加载配置文件

public classPropsUtil {/*** 加载配置文件

*

*@paramfileName 配置文件名

*@return

*/

public staticProperties loadProps(String fileName) {

Properties props= null;

InputStream is= null;try{

is=Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);if (is == null) {throw new FileNotFoundException(fileName + " file is not found");

}

props= newProperties();

props.load(is);

}catch(IOException ioe) {

ioe.printStackTrace();

}finally{if (is != null) {try{

is.close();

}catch(IOException ioe) {

ioe.printStackTrace();

}

}

}returnprops;

}/*** 获取字符型属性(默认值为空字符串)

*

*@paramprops

*@paramkey

*@return

*/

public staticString getString(Properties props, String key) {return getString(props, key, "");

}/*** 获取字符型属性(可指定默认值)

*

*@paramprops

*@paramkey

*@paramdefaultValue

*@return

*/

public staticString getString(Properties props, String key, String defaultValue) {

String value=defaultValue;if(props.containsKey(key)) {

value=props.getProperty(key);

}returnvalue;

}

}

获取配置文件属性

加载了配置文件,需要编写一个类ConfigHelper来获取配置文件属性。框架初始化需要根据配置文件来初始化应用。框架默认配置文件为config.properties,只有创建了名为config.properties的配置文件,框架才能运行。

/*** 获取配置文件属性*/

public classConfigHelper {private static final Properties CONFIG_PROPS = PropsUtil.loadProps("config.properties");//默认配置文件为config.properties

/*** 获取应用基础包名

*

*@return

*/

public staticString getAppBasePackage() {returnPropsUtil.getString(CONFIG_PROPS, Constant.APP_BASE_PACKAGE);

}/*** 获取JSP路径

*

*@return

*/

public staticString getAppJspPath() {returnPropsUtil.getString(CONFIG_PROPS, Constant.APP_JSP_PACKAGE);

}/*** 获取应用静态资源路径

*

*@return

*/

public staticString getAppAssetPath() {return PropsUtil.getString(CONFIG_PROPS, Constant.APP_ASSET_PATH, "/asset/");

}

}

类加载器

实现一个类加载器ClassUtil来加载基础包下的所有的类。只有加载了这些类,框架才能对其进行初始化。获取当前线程的ClassLoader通过这个类加载器来加载类,获取指定包名下的所有的类,需要指定根据包名并将其转换为文件路径,读取class文件或jar包,获取指定的类名去加载类。

/*** 获取类加载器

*

*@return

*/

public staticClassLoader getClassLoader() {returnThread.currentThread().getContextClassLoader();

}/*** 加载类

*

*@paramclassName 类名称

*@paramisInitialized 是否执行类的静态代码块

*@return

*/

public static Class> loadClass(String className, booleanisInitialized) {

Class>clazz;try{

clazz=Class.forName(className, isInitialized, getClassLoader());

}catch(ClassNotFoundException cnfe) {

cnfe.printStackTrace();throw newRuntimeException(cnfe);

}returnclazz;

}/*** 获取指定包下所有类

*

*@parampackageName

*@return

*/

public static ArrayList>getClasses(String packageName) {

ArrayList> classes = new ArrayList<>();try{

Enumeration urls = getClassLoader().getResources(packageName.replace(".", "/"));while(urls.hasMoreElements()) {

URL url=urls.nextElement();if (url != null) {

String protocol=url.getProtocol();if (protocol.equals("file")) {

String packagePath= url.getPath().replaceAll("%20", " ");

addClass(classes, packagePath, packageName);

}else if (protocol.equals("jar")) {

JarURLConnection jarURLConnection=(JarURLConnection) url.openConnection();if (jarURLConnection != null) {

JarFile jarFile=jarURLConnection.getJarFile();if (jarFile != null) {

Enumeration jarEntries =jarFile.entries();while(jarEntries.hasMoreElements()) {

JarEntry jarEntry=jarEntries.nextElement();

String jarEntryName=jarEntry.getName();if (jarEntryName.equals(".class")) {

String className= jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");

doAddClass(classes, className);

}

}

}

}

}

}

}

}catch(Exception e) {

e.printStackTrace();throw newRuntimeException(e);

}returnclasses;

}

...

...

...

}

定义注解

本框架采用注解来标识Controller,Service类。所以需要定义注解来标识那些类是Controller,Controller类中那些方法响应url请求等。

控制器类上使用Controller注解,在控制器类的方法上使用RequestMapping注解,使用Autowired注解将服务类依赖注入进来。服务类使用Service注解。

/*** 控制器注解*/@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)public @interfaceController {

}/*** 请求方法注解*/@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)public @interfaceRequestMapping {//请求类型路径

String path();//请求方法

String method();

}/*** 服务类注解*/@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)public @interfaceService {

}/*** 依赖注入注解*/@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)public @interfaceAutowired {

}

获取类

Controller,Service类是框架需要管理的类,把他们统称为Bean类。实现一个类可以获取应用所有的Controller,Service类。首先调用ConfigHelper.getAppBasePackage()获取基础包名,然后调用ClassUtil.getClasses(basePackage)加载该基础包名下所有的类,保存在变量ArrayList> classes中;再遍历ArrayList> classes获取Controller,Service等类。

//获取类

public classClassHelper {//基础包名下所有的类

private static final ArrayList>classes;static{

String basePackage=ConfigHelper.getAppBasePackage();

classes=ClassUtil.getClasses(basePackage);

}/*** 获取基础包名下所有的类

*

*@return

*/

public static ArrayList>getClasses() {returnclasses;

}/*** 获取所有Service类

*

*@return

*/

public static ArrayList>getServiceClasses() {

ArrayList> sc = new ArrayList<>();//补全代码

returnsc;

}/*** 获取所有Controller类

*

*@return

*/

public static ArrayList>getControllerClasses() {

ArrayList> cc = new ArrayList<>();for (Class>c : classes) {if (c.isAnnotationPresent(Controller.class)) {

cc.add(c);

}

}returncc;

}/*** 框架Bean容器主要管理Service,Controller类

*

*@return

*/

public static ArrayList>getBeanClasses() {

ArrayList> bc = new ArrayList<>();

bc.addAll(getServiceClasses());

bc.addAll(getControllerClasses());returnbc;

}

}

现在来测试类加载器和获取类是否正确,配置文件将基础包名设为app.base_package=com.hubwiz.web.controller,在这个包下,实现了三个类HomeController类(带Controller注解),PersonService类(带Service注解),Person类。public static voidmain(String[] args) {

ArrayList> ces =ClassHelper.getClasses();for (Class>c : ces) {

System.out.println(c.getSimpleName());

}

}

Bean工厂

回顾下前面的知识,通过加载配置文件获取应用基础包名,加载基础包名下所有的类,获取Controller,Service类。到目前为止,我们只是加载了类,但是无法通过获取的类来实例化对象。因此需要一个反射工具,来实例化类。

创建一个Bena工厂,来生产(实例化Bean类对象)Bean。newInstance()方法,实例化目标类;invokeMethod()通过反射机制来调用类中的方法;setField()通过反射机制为类成员遍历赋值。

//Bean工厂

public classBeanFactory {/*** 创建实例

*

*@paramclazz

*@return

*/

public static Object newInstance(Class>clazz) {

Object instance;try{

instance=clazz.newInstance();

}catch(Exception e) {throw newRuntimeException(e);

}returninstance;

}/*** 方法调用

*

*@paramobj

*@parammethod

*@paramargs

*@return

*/

public staticObject invokeMethod(Object obj, Method method, Object... args) {

Object result;try{

method.setAccessible(true);

result=method.invoke(obj, args);

}catch(Exception e) {throw newRuntimeException(e);

}returnresult;

}/*** 设置成员变量值

*

*@paramobj

*@paramfield

*@paramvalue*/

public static voidsetField(Object obj, Field field, Object value) {try{

field.setAccessible(true);

field.set(obj, value);

}catch(Exception e) {throw newRuntimeException(e);

}

}

}

Bean容器

前面在ClassHelper定义了方法getBeanClasses()来获取Bean容器需要管理的所有Controller,Service类,获取这些类以后,调用BeanFactory.newInstance(Class clazz)方法来实例化类的对象,缓存在Map beanContainer中,需要随时获取。Map说明:使用类全名称作为key,类的实例对象作为value值。

BeanContainer初始化:首先调用ClassHelper.getBeanClasses()获取所有的Bean类,调用Bean工厂方法newInstance()方法来实例化Bean类,保存在beanContainer中。通过类全名称从beanContainer获取需要的Bean实例对象。

/*** Bean容器*/

public classBeanContainer {/*** 存放Bean类名称和Bean实例的映射关系*/

private static final Map beanContainer = new HashMap<>();static{

ArrayList> beanClasses =ClassHelper.getBeanClasses();for (Class>beanClass : beanClasses) {

Object obj=BeanFactory.newInstance(beanClass);

beanContainer.put(beanClass.getName(), obj);

}

}/*** 获取Bean映射

*

*@return

*/

public static MapgetBeanContainer() {returnbeanContainer;

}/*** 获取Bean实例*/

public static T getBean(String className) {if (!beanContainer.containsKey(className)) {throw new RuntimeException("can not get bean by className: " +className);

}return(T) beanContainer.get(className);

}/*** 设置Bean实例*/

public static voidsetBean(String className, Object obj) {//补全代码

}

}

依赖注入

首先来了解下Spring框架的核心机制:依赖注入。当某个Java实例(调用者)需要另一个Java实例(被调用者)时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。在依赖注入模式下,创建调用者的工作不再由调用者来完成,因此称为控制反转(Ioc);创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也成为依赖注入(DI)。

Controller中定义Service成员变量,需要通过框架自身来实例化。

首先通过beanContainer获取所有的Bean类全名称和Bean实例,遍历获取所有的Controller类,通过反射获取类中的成员变量,遍历这些成员变量看是否有Autowired注解,若有,从beanContainer中获取Bean实例,然后调用Bean工厂setField()方法将获取的Bean实例赋值给成员变量。

/*** 依赖注入*/

public final classIocHelper {static{

Map beanContainer =BeanContainer.getBeanContainer();if(CollectionUtil.isNotEmpty(beanContainer)) {

initIOC(beanContainer);

}

}private static void initIOC( MapbeanContainer) {for (Map.EntrybeanEntry : beanContainer.entrySet()) {

String className=beanEntry.getKey();

Object beanInstance=beanEntry.getValue();

Class> beanClass = null;try{

beanClass=Class.forName(className);

System.out.println(className);

}catch(ClassNotFoundException e) {

e.printStackTrace();

}//Controller类中定义的属性

Field[] beanFields =beanClass.getDeclaredFields();if(ArrayUtil.isNotEmpty(beanFields)) {for(Field beanField : beanFields) {//带有Autowired注解的成员变量

if (beanField.isAnnotationPresent(Autowired.class)) {//成员变量的类

Class> beanFieldClass =beanField.getType();

Object beanFieldInstance=beanContainer.get(beanFieldClass.getName());if (beanFieldInstance != null) {//依赖注入

BeanFactory.setField(beanInstance, beanField, beanFieldInstance);

}

}

}

}

}

}

}

Request

Controller类中带有RequestMapping注解的方法处理特定URL请求,如何判断当前请求 URL&Method 对应那个Controller & method,这是接下来要实现的。通过反射可以获取Controller中带有RequestMapping注解的方法,进而获得RequestMapping注解中请求方法和请求路径。封装一个请求对象request与处理request对象handler,将request与handler建立一个映射关系。

请求对象request:包括请求路径path;请求方法method两个属性。

处理request对象handler:包括Controller类;带有RequestMapping注解的方法method。

/*** 封装请求信息*/

public classRequest {//请求方法

privateString requestMethod;//请求路径

privateString requestPath;publicRequest(String requestMethod,String requestPath) {this.requestMethod =requestMethod;this.requestPath =requestPath;

}publicString getRequestMethod() {returnrequestMethod;

}publicString getRequestPath() {returnrequestPath;

}

@Overridepublic inthashCode() {return HashCodeBuilder.reflectionHashCode(this);

}

@Overridepublic booleanequals(Object obj) {return EqualsBuilder.reflectionEquals(this,obj);

}

}/*** 处理Request请求对应Controller & method*/

public classHandler {private Class>controllerClass;privateMethod method;public Handler(Class>controllerClass,Method method) {this.controllerClass =controllerClass;this.method =method;

}public Class>getControllerClass() {returncontrollerClass;

}publicMethod getMethod() {returnmethod;

}

}

RequestMapping

编写一个类ControllerHelper,将Controller类中定义处理Requet的方法,与Handler绑定。通过请求路径与请求方法我们能方便找到处理这个请求的Controller类和method。

public classControllerHelper {//请求request与处理请求handler映射关系

private static final Map RequestMap = new HashMap<>();static{

ArrayList> controllerClasses =ClassHelper.getControllerClasses();if(CollectionUtil.isNotEmpty(controllerClasses)) {

initRequestMapp(controllerClasses);

}

}private static void initRequestMapp(ArrayList>controllerClasses) {for (Class>controllerClass : controllerClasses) {

Method[] methods=controllerClass.getDeclaredMethods();if(ArrayUtil.isNotEmpty(methods)) {for(Method method : methods) {//带有RequestMapping注解的方法

if (method.isAnnotationPresent(RequestMapping.class)) {

RequestMapping rm= method.getAnnotation(RequestMapping.class);//请求路径与请求方法

Request request = newRequest(rm.method(), rm.path());//对应请求路径与请求方法的Controller和method

Handler handler = newHandler(controllerClass, method);

RequestMap.put(request, handler);

}

}

}

}

}/*** 获取handler

*

*@paramrequestMethod

*@paramrequestPath

*@return

*/

public staticHandler getHandler(String requestMethod, String requestPath) {

Request request= newRequest(requestMethod, requestPath);returnRequestMap.get(request);

}

}

初始化类

框架基本搭建起来了,现在需要编写一个类来初始化应用。

初始化步骤:

1、加载ClassHelper类,通过这个类加载基础包名下所有的类。

2、加载BeanContainer类,将基础包名下所有Bean类,通过Bean工厂实例化保存在Bean容器。

3、加载IocHelper类,实例化Bean类,需要为Controller类中带有Autowired注解的属性赋值。

4、加载ControllerHelper类,将Controller类中带有RequestMapping注解的方法,建立与请求路径和请求方法的映射关系,这样框架才能找到处理请求对应的方法。

/*** 初始化框架*/

public classLoader {public static voidinit() {

Class>[] cs = {ClassHelper.class,

BeanContainer.class,

IocHelper.class,

ControllerHelper.class};for (Class>c: cs) {

ClassUtil.loadClass(c.getName(),true);

}

}

}

请求参数

通常前端通过form表格的形式向后台发送数据,需要一个类封装从HttpServletRequest请求对象中获取所有的参数,然后传递给处理方法。首先解析请求参数(form表单数据),将其封装成Param类中,传递给Controller的方法处理。

通过request.getParameterNames()将发送请求页面中form表单所具有name属性的表单对象获取,request.getParameterValues(name)获取其值,生成FormParam保存在Param中。

/*** 解析请求参数,form表单数据*/

public classParameterUtil {public static Param createParam(HttpServletRequest request) throwsIOException {return newParam(parseParameterNames(request));

}private static MapparseParameterNames(HttpServletRequest request) {

Map formParams = new HashMap<>();//将发送请求页面中form表单所具有name属性的表单对象获取

Enumeration paramNames =request.getParameterNames();while(paramNames.hasMoreElements()) {

String fieldName=paramNames.nextElement();

String[] fieldValues=request.getParameterValues(fieldName);if(ArrayUtil.isNotEmpty(fieldValues)) {

Object fieldValue;if (fieldValues.length == 1) {

fieldValue= fieldValues[0];

}else{

StringBuilder sb= new StringBuilder("");for (int i = 0; i < fieldValues.length; ++i) {

sb.append(fieldValues[i]);if (i != fieldValues.length - 1) {

sb.append(StringUtil.separator);

}

}

fieldValue=sb.toString();

}

formParams.put(fieldName,fieldValue);

}

}returnformParams;

}

}

Param请求参数对象,封装了前端提交的form表格数据。

/*** 请求参数对象*/

public classParam {private MapformParams;public Param(MapformParams) {this.formParams =formParams;

}/*** 判断参数是否为空

*

*@returnboolean*/

public booleanisEmpty() {returnCollectionUtil.isEmpty(formParams);

}public MapgetFormParams() {returnformParams;

}/*** 根据参数名取String型参数值

*

*@paramname

*@return

*/

publicString getString(String name) {returnCastUtil.castString(formParams.get(name));

}public doublegetDouble(String name) {returnCastUtil.castDouble(formParams.get(name));

}public longgetLong(String name) {returnCastUtil.castLong(formParams.get(name));

}public intgetInt(String name) {returnCastUtil.castInt(formParams.get(name));

}publicBoolean getBoolean(String name) {returnCastUtil.castBoolean(formParams.get(name));

}

}

模型数据与视图

在处理请求时,通常会返回视图JSP页面和数据。所以现在需要将视图JSP路径和数据封装在一起返回。如果只返回数据,则返回JSON格式数据。

返回视图JSP,视图中包含视图JSP路径和视图中所需的数据:

public classModelAndView {//返回JSP路径

privateString path;//模型数据

private MapmData;publicModelAndView(String path) {this.path =path;

mData= new HashMap<>();

}publicModelAndView addmData(String key, Object obj) {

mData.put(key,obj);return this;

}publicString getPath() {returnpath;

}public MapgetmData() {returnmData;

}

}

返回数据,框架将其写入HttpServletRespone对象中,输出到客户端浏览器。

/*** 返回数据*/

public class Data{privateT datas;publicData(T datas) {this.datas =datas;

}publicT getDatas() {returndatas;

}

}

数据格式转换

由于返回的数据格式为JSON,现在需要将POJO转换成JSON格式。采用Jackson框架。

/*** POJO转换为JSON*/

public classJsonUtil {/*** 将POJO转化为JSON

*

*@paramobj

*@param

*@return

*/

public static String toJSON(T obj) {

String json= null;try{

ObjectMapper mapper= newObjectMapper();

json=mapper.writeValueAsString(obj);

}catch(Exception e) {

e.printStackTrace();

}returnjson;

}/*** 将JSON转化为POJO

*

*@paramjson

*@paramclazz

*@param

*@return

*/

public static T fromJSON(String json, Classclazz) {

T pojo= null;try{

ObjectMapper mapper= newObjectMapper();

pojo=mapper.readValue(json, clazz);

}catch(Exception e) {

e.printStackTrace();

}returnpojo;

}

}

请求转发器

请求转发器是框架的核心。请求转发器转发器用来处理所有的请求。DispatherServlet继承HttpServlet,在init()方法调用Loader.init()来初始化框架和应用。service()方法响应所有的请求。

请求转发过程:

1、通过req.getMethod().toLowerCase()获取请求方法(get,post,put delete);req.getContextPath()获取请求路径,根据请求路径和请求方法调用ControllerHelper.getHandler()方法获取处理这个请求对应的handler。

2、Hanler封装处理请求的Controller和方法,所有获取的handler,就可以获取处理请求的Controller和方法method。

3、获取了处理这个请求的Controller类,现在需要在Bean获取这个Controller类的实例对象,调用BeanContainer.getBean()来获取Controller类的实例对象。

4、调用ParameterUtil.createParam(req)来解析请求参数。

5、调用handler.getMethod()获取处理这个请求的方法,通过反射机制BeanFactory.invokeMethod()来调用这个方法,处理这个请求的方法就会来处理这个请求。

6、根据返回的结果是ModelAndView还是Data来处理返回问题。返回结果为ModelAndView,调用req.getRequestDispatcher(ConfigHelper.getAppJspPath() + path).forward(req, resp)将页面响应转发到ConfigHelper.getAppJspPath() + path;返回结果为Data,将返回结果POJO转换为JSON格式,写入HttpServletRespone对象中,输出到客户端浏览器。

/*** 请求转发器*/@WebServlet(urlPatterns= "/",loadOnStartup = 0)public class DispatherServlet extendsHttpServlet {

@Overridepublic void init(ServletConfig config) throwsServletException {

Loader.init();//初始化框架&应用

ServletContext sc =config.getServletContext();//注册JSP的Servlet

ServletRegistration jspServlet = sc.getServletRegistration("jsp");

jspServlet.addMapping(ConfigHelper.getAppJspPath()+ "*");//注册处理静态资源的Servlet

ServletRegistration defaultServlet = sc.getServletRegistration("default");

defaultServlet.addMapping(ConfigHelper.getAppAssetPath()+ "*");

}

@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException {//获取请求方法

String requestMethod =req.getMethod().toLowerCase();//请求路径url

String url =req.getRequestURI();

String contextPath=req.getContextPath();

String requestPath= null;if (contextPath != null && contextPath.length() > 0) {

requestPath=url.substring(contextPath.length());

}//获取处理这个请求的handler

Handler handler =ControllerHelper.getHandler(requestMethod, requestPath);//System.out.println(requestMethod + " " + requestPath);

if (handler != null) {

Class> controllerClass =handler.getControllerClass();

Object controllerBean=BeanContainer.getBean(controllerClass.getName());//解析请求参数

Param param =ParameterUtil.createParam(req);

Object result;//请求返回对象

Method method = handler.getMethod();//处理请求的方法

if(param.isEmpty()) {

result=BeanFactory.invokeMethod(controllerBean, method);

}else{

result=BeanFactory.invokeMethod(controllerBean, method, param);

}if (result instanceofModelAndView) {

handleViewResult((ModelAndView) result, req, resp);

}else{

handleDataResult((Data) result, resp);

}

}

}//返回为JSP页面

private static voidhandleViewResult(ModelAndView view, HttpServletRequest req, HttpServletResponse resp)throwsIOException, ServletException {

String path=view.getPath();if(StringUtil.isNotEmpty(path)) {if (path.startsWith("/")) {

resp.sendRedirect(req.getContextPath()+path);

}else{

Map data =view.getmData();for (Map.Entryentry : data.entrySet()) {

req.setAttribute(entry.getKey(), entry.getValue());

}//forward将页面响应转发到ConfigHelper.getAppJspPath() + path//补全代码

}

}

}//返回JSON数据

private static voidhandleDataResult(Data data, HttpServletResponse resp)throwsIOException {

Object model=data.getData();if (model != null) {

resp.setContentType("application/json");

resp.setCharacterEncoding("UTF-8");

PrintWriter writer=resp.getWriter();

String json=JsonUtil.toJSON(model);

writer.write(json);

writer.flush();

writer.close();

}

}

}

---汇智网

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值