spring mvc 简单实现及相关配置实现
配置文件 actio.xml
<?xml version="1.0" encoding="UTF-8"?> <controller> <action name="questionList" class="com.augmentum.oes.controller.QuestionController" method="list" httpMethod="GET,POST"> <!-- <result name="success" view="" redirect="true"/> --> </action> <action name="questionDelete" class="com.augmentum.oes.controller.QuestionController" method="delete"/> <action name="questionEdit" class="com.augmentum.oes.controller.QuestionController" method="edit"/> <action name="questionAdd" class="com.augmentum.oes.controller.QuestionController" method="add" httpMethod="GET,POST"/> <action name="login" class="com.augmentum.oes.controller.UserController" method="login" > <result name="input" view="WEB-INF/jsp/login.jsp" redirect="false" /> <result name="hadLogin" view="questionList.action" redirect="true" viewParameter=""/> </action> <action name="login" class="com.augmentum.oes.controller.UserController" method="saveLogin" httpMethod="POST"/> <action name="logout" class="com.augmentum.oes.controller.UserController" method="logout"/> </controller>
2 存储配置文件的model
package com.augmentum.oes.common; import java.util.HashMap; import java.util.Map; public class ActionConfig { private String clsName; private String methodName; private String[] httpMethod; private Map<String, ResultConfig> results = new HashMap<String, ResultConfig>(); public Map<String, ResultConfig> getResults() { return results; } public ResultConfig getResult(String resultKey) { return results.get(resultKey); } public void addResults(String name, ResultConfig resultConfig) { results.put(name, resultConfig); } public void setResults(Map<String, ResultConfig> results) { if (results == null ) { results = new HashMap<String, ResultConfig>(); } this.results = results; } public ActionConfig() { super(); } public String[] getHttpMethod() { return httpMethod; } public void setHttpMethod(String[] httpMethod) { this.httpMethod = httpMethod; } public ActionConfig(String clsName, String methodName) { this.clsName = clsName; this.methodName = methodName; } public String getClsName() { return clsName; } public void setClsName(String clsName) { this.clsName = clsName; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } }
package com.augmentum.oes.common; import java.util.ArrayList; import java.util.List; public class ResultConfig { private String name; private String view; private boolean redirect; private List<ViewParameterConfig> viewParameterConfigs = new ArrayList<ViewParameterConfig>(); public void addViewParameterConfigs(ViewParameterConfig viewParameterConfig) { this.viewParameterConfigs.add(viewParameterConfig); } public List<ViewParameterConfig> getViewParameterConfigs() { return viewParameterConfigs; } public void setViewParameterConfigs(List<ViewParameterConfig> viewParameterConfigs) { if (viewParameterConfigs == null) { this.viewParameterConfigs = new ArrayList<ViewParameterConfig>(); } this.viewParameterConfigs = viewParameterConfigs; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getView() { return view; } public void setView(String view) { this.view = view; } public boolean isRedirect() { return redirect; } public void setRedirect(boolean redirect) { this.redirect = redirect; } }
package com.augmentum.oes.common; public class ViewParameterConfig { private String name; private String from; public ViewParameterConfig(String name, String from) { super(); this.name = name; this.from = from; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } }
3.创建controller
package com.augmentum.oes.controller; import java.util.Map; import com.augmentum.oes.Constants; import com.augmentum.oes.common.ModelAndView; import com.augmentum.oes.exception.ParameterException; import com.augmentum.oes.exception.ServiceException; import com.augmentum.oes.model.User; import com.augmentum.oes.service.UserService; import com.augmentum.oes.service.impl.UserServiceImpl; import com.augmentum.oes.util.StringUtil; public class UserController { private final String LOGIN_PAGE = "WEB-INF/jsp/login.jsp"; public ModelAndView login(Map<String, String> request,Map<String, Object> session) { User user = (User) session.get(Constants.USER); ModelAndView modelAndView = new ModelAndView(); if (user != null) { modelAndView.setRedirect(true); modelAndView.setView("input"); } else { String go = request.get("go"); if (StringUtil.isEmpty(go)) { go = ""; } modelAndView.addObject("go", go); modelAndView.setView(LOGIN_PAGE); } return modelAndView; } public ModelAndView saveLogin(Map<String, String> request,Map<String, Object> session){ String userName = request.get("userName"); String password = request.get("password"); ModelAndView modelAndView = new ModelAndView(); try { User user = null; UserService userService = new UserServiceImpl(); user = userService.login(userName, password); user.setPassword(null); modelAndView.setSessionAttribute(Constants.USER, user); String go = request.get("go"); String queryString = request.get("queryString"); if (!StringUtil.isEmpty(queryString)) { if (queryString.startsWith("#")) { queryString = queryString.substring(1); } go = go +"?"+queryString; } if (StringUtil.isEmpty(go)) { modelAndView.setView("questionList.action"); modelAndView.setRedirect(true); } else { modelAndView.setView(go); modelAndView.setRedirect(true); } } catch (ParameterException parameterException) { Map<String, String> errorFields = parameterException.getErrorFields(); modelAndView.addObject(Constants.ERROR_FIELDS, errorFields); modelAndView.setView(LOGIN_PAGE); } catch (ServiceException serviceException) { modelAndView.addObject(Constants.TIP_MESSAGE, serviceException.getMessage()+serviceException.getCode()); modelAndView.setView(LOGIN_PAGE); } return modelAndView; } public ModelAndView logout(Map<String, String> request,Map<String, Object> session){ ModelAndView modelAndView = new ModelAndView(); if (session == null ) { modelAndView.setRedirect(true); modelAndView.setView("login.action"); } else { //wai bu map set is null session.put(Constants.USER, null); modelAndView.setSessions(session); modelAndView.setRedirect(true); modelAndView.setView("login.action"); } return modelAndView; } }
加入ModelAndView 存入request和response等 与dispather进行交互
package com.augmentum.oes.common; import java.util.HashMap; import java.util.Map; public class ModelAndView { private Map<String, Object> sessions = new HashMap<String, Object>(); private Map<String, Object> requests = new HashMap<String, Object>(); private String view; private boolean isRedirect = false; public Map<String, Object> getSessions() { return sessions; } public void setSessions(Map<String, Object> sessions) { this.sessions = sessions; } public Map<String, Object> getRequests() { return requests; } public void setRequests(Map<String, Object> requests) { this.requests = requests; } public String getView() { return view; } public void setView(String view) { this.view = view; } public boolean isRedirect() { return isRedirect; } public void setRedirect(boolean isRedirect) { this.isRedirect = isRedirect; } public void addObject(String key,Object value) { requests.put(key, value); } public void setSessionAttribute(String key, Object object) { sessions.put(key, object); } public void removeSessionAttribute(String key) { sessions.remove(key); } }
4.创建单例DispatcherServlet 初始化时 读取配置,进行反射转发
package com.augmentum.oes.servlet; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import com.augmentum.oes.common.ActionConfig; import com.augmentum.oes.common.ModelAndView; import com.augmentum.oes.common.ResultConfig; import com.augmentum.oes.common.ViewParameterConfig; import com.augmentum.oes.util.StringUtil; public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 1L; private String suffix = ".action"; private Map<String, ActionConfig> actionConfigs = new HashMap<String, ActionConfig>(); public DispatcherServlet() { super(); } @Override public void init(ServletConfig config) throws ServletException { super.init(config); String suffixFromConf = config.getInitParameter("suffix"); if (!StringUtil.isEmpty(suffixFromConf)) { suffix = suffixFromConf; } InputStream inputStream = null; try { inputStream = DispatcherServlet.class.getClassLoader().getResourceAsStream("action.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(inputStream); Element element = document.getDocumentElement(); NodeList actionNodes = element.getElementsByTagName("action"); if (actionNodes == null) { return; } int actionLength = actionNodes.getLength(); for(int i=0; i < actionLength; i++) { Element actionElement = (Element) actionNodes.item(i); ActionConfig actionConfig = new ActionConfig(); String name = actionElement.getAttribute("name"); String clsName = actionElement.getAttribute("class"); actionConfig.setClsName(clsName); String methodName = actionElement.getAttribute("method"); actionConfig.setMethodName(methodName); String httpMethod = actionElement.getAttribute("httpMethod"); if (StringUtil.isEmpty(httpMethod)) { httpMethod = "GET"; } String[] httpMethodArr = httpMethod.split(","); actionConfig.setHttpMethod(httpMethodArr); for (String httpMethodItem:httpMethodArr) { actionConfigs.put(name+suffix+"#"+httpMethodItem.toUpperCase(), actionConfig); } //continue jiexi result NodeList resultNodes = actionElement.getElementsByTagName("result"); if (resultNodes != null) { int resultLength = resultNodes.getLength(); for (int j = 0; j < resultLength; j++) { Element resultElement = (Element) resultNodes.item(j); ResultConfig resultConfig = new ResultConfig(); String resultName = resultElement.getAttribute("name"); resultConfig.setName(name); String resultView = resultElement.getAttribute("view"); resultConfig.setName(resultView); String resultRedirect = resultElement.getAttribute("redirect"); if (StringUtil.isEmpty(resultRedirect)) { resultConfig.setRedirect(false); } resultConfig.setRedirect(Boolean.parseBoolean(resultRedirect)); String viewParameter =resultElement.getAttribute("viewParameter"); if(StringUtil.isEmpty(viewParameter)) { String[] viewParameterArr = viewParameter.split(","); for (String viewParameterItem : viewParameterArr) { String[] viewParameterItemArr = viewParameterItem.split(":"); String key =viewParameterItemArr[0]; String from ="attribute"; if (viewParameterItemArr.length==2) { from = viewParameterItemArr[1].trim(); } ViewParameterConfig viewParameterConfig = new ViewParameterConfig(key,from); resultConfig.addViewParameterConfigs(viewParameterConfig); } } actionConfig.addResults(resultName, resultConfig); } } } } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uri = request.getRequestURI(); String requestUri = uri.substring(request.getContextPath().length()+1); if(requestUri == null || requestUri.equals("")) { requestUri = "login"+this.suffix; } String httpMethod = request.getMethod(); ActionConfig actionConfig = actionConfigs.get(requestUri+"#"+httpMethod.toUpperCase()); HttpSession session = request.getSession(); if (actionConfig != null) { String clsName = actionConfig.getClsName(); try { Class<?>[] param = new Class[2]; param[0] = Map.class; param[1] = Map.class; Class<?> cls = Class.forName(clsName); Object controller = cls.newInstance(); String methodName = actionConfig.getMethodName(); Method method = cls.getMethod(methodName, param); //get session date send in; Map<String, Object> sessionMap = new HashMap<String, Object>(); Enumeration<String> toSessionKeys = session.getAttributeNames(); while(toSessionKeys.hasMoreElements()){ String toKey = toSessionKeys.nextElement(); sessionMap.put(toKey, session.getAttribute(toKey)); } //send parmeter Map<String, Object> parameterMap = new HashMap<String, Object>(); Enumeration<String> toRequestKeys = request.getParameterNames(); while(toRequestKeys.hasMoreElements()){ String toKey = toRequestKeys.nextElement(); parameterMap.put(toKey, request.getParameter(toKey)); } Object[] objects = new Object[2]; objects[0] = parameterMap; objects[1] = sessionMap; ModelAndView modelAndView = (ModelAndView) method.invoke(controller, objects); //receive session out Map<String, Object> sessions = modelAndView.getSessions(); Set<String> keys = sessions.keySet(); for (String key : keys) { session.setAttribute(key, sessions.get(key)); } //receive session out Map<String, Object> requests = modelAndView.getRequests(); Set<String> keys2 = requests.keySet(); for (String key : keys2) { request.setAttribute(key, requests.get(key)); } String view = modelAndView.getView(); //modelAndView == result view ResultConfig resultConfig = actionConfig.getResult(view); if (resultConfig == null) { if (modelAndView.isRedirect()) { response.sendRedirect(request.getContextPath()+"/"+view); } else { request.getRequestDispatcher(view).forward(request, response); } } else { String resultView = request.getContextPath()+"/"+resultConfig.getView(); if (resultConfig.isRedirect()) { List<ViewParameterConfig> viewParameterConfigs = resultConfig.getViewParameterConfigs(); if (viewParameterConfigs ==null || viewParameterConfigs.isEmpty()) { response.sendRedirect(resultView); } else { StringBuilder sb = new StringBuilder(); for (ViewParameterConfig viewParameterConfig : viewParameterConfigs) { String name = viewParameterConfig.getName(); String from = viewParameterConfig.getFrom(); String value = ""; if ("attribute".equals(from)) { value = (String) request.getAttribute(name); } else if ("parameter".equals(from)) { value = request.getParameter(name); } else if ("session".equals(from)) { value = (String) request.getSession().getAttribute(name); } else { value = (String) request.getAttribute(name); } if (StringUtil.isEmpty(value)) { sb.append(name + "=" + "&"); } } if (resultView.indexOf("?") > 0) { resultView = resultView + "&" +sb.toString(); } else { resultView = resultView + "?" + sb.toString(); } response.sendRedirect(resultView); } } else { request.getRequestDispatcher(resultView).forward(request, response); } } } catch (Exception e) { e.printStackTrace(); response.sendError(500); } } else { response.sendError(404); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
web.xml配置
<servlet> <display-name>DispatcherServlet</display-name> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>com.augmentum.oes.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>suffix</param-name> <param-value>.action</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
ThreadLocal controller 中获得request ThreadLocal<Appcontext> = = Map <Thread,AppContext>
package com.augmentum.oes.common; import java.util.HashMap; import java.util.Map; public class AppContext { private static ThreadLocal<AppContext> appContextMap = new ThreadLocal<AppContext>(); private Map<String, Object> objects = new HashMap<String, Object>(); public static ThreadLocal<AppContext> getAppContextMap() { return appContextMap; } public static void setAppContextMap(ThreadLocal<AppContext> appContextMap) { AppContext.appContextMap = appContextMap; } public Map<String, Object> getObjects() { return objects; } public void addObject(String key, Object object) { this.objects.put(key, object); } public Object getObject(String key) { return objects.get(key); } public void clear() { objects.clear(); } public void setObjects(Map<String, Object> objects) { if (objects == null) { objects = new HashMap<String, Object>(); } this.objects = objects; } private AppContext() {}; public static AppContext getAppContext() { AppContext appContext = appContextMap.get(); if (appContext == null) { appContext = new AppContext(); appContextMap.set(appContext); } return appContextMap.get(); } }
package com.augmentum.oes.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.augmentum.oes.Constants; import com.augmentum.oes.common.AppContext; public class AppContextFilter implements Filter { public AppContextFilter() { } @Override public void destroy() { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; AppContext appContext = AppContext.getAppContext(); appContext.addObject(Constants.APP_CONTEXT_REQUEST, request); appContext.addObject(Constants.APP_CONTEXT_RESPONSE, response); try { chain.doFilter(request, response); } catch (IOException ioException) { throw ioException; } catch (ServletException servletException) { throw servletException; } catch (RuntimeException runtimeException) { throw runtimeException; } finally { appContext.clear(); } } @Override public void init(FilterConfig fConfig) throws ServletException { } }
用AppContext 获取 connection 在 不需要的时 自定义关闭
Connection
Manager
boolean needMyClose = false; Connection conn = (Connection) AppContext.getAppContext().getObject("APP_REQUEST_THREAD_CONNECTION"); if (conn == null) { conn = DBUtil.getConnection(); AppContext.getAppContext().addObject("APP_REQUEST_THREAD_CONNECTION", conn); needMyClose = true; } if (needMyClose) { conn = (Connection) AppContext.getAppContext().getObject("APP_REQUEST_THREAD_CONNECTION"); DBUtil.close(conn, null, null); }
在JDBCTemplete 同样 ,当获取到threadLocal中的conn时 , 何处创建何处关闭
使用 springmvc
编码拦截器 <filter> <filter-name>characterEncoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <listener> <display-name>contextLoaderListener</display-name> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
创建springmvc.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <mvc:annotation-driven/> //注解驱动 不用映射器和适配器 <mvc:resources location="/static/" mapping="/static/**"/> 过滤掉静态资源 <context:component-scan base-package="com.**.controller.**"/> 扫描包 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
在对应包下创建controler
@RequestMapping(value="/delete",method=RequestMethod.GET) public ModelAndView delete(@RequestParam(value="deleteList",defaultValue = "")int[] deleteList, @RequestParam(value="questiondesc",defaultValue="")String questiondesc, int currentPage, int pageSize) @RequestParam ?键=值 @PathVariable /值/值 @Requestbody 将前台ajax 传过来的json数据 传入到对象中 对于不需要传入的在model的get加@JsonIgnore @JsonSerialize(using = 工具类) 将日期转为字符串 工具类继承JsonSeriablize<Date>
http://note.youdao.com/noteshare?id=5c61f7e4e5121e2b49953df8001d295c
转换时间
绑定方法
自定义参数绑定 需求 根据业务需求自定义日期格式进行参数绑定。 propertyEditor 使用WebDataBinder 在controller方法中通过@InitBinder标识方法为参数绑定方法,通过WebDataBinder注册属性编辑器,问题是此方法只能在单个controller类中注册。 /** * 注册属性编辑器(字符串转换为日期) */ @InitBinder public void initBinder(WebDataBinder binder) throws Exception { binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true)); } 使用WebBindingInitializer 如果想多个controller需要共同注册相同的属性编辑器,可以实现PropertyEditorRegistrar接口,并注入webBindingInitializer中。 如下: 编写CustomPropertyEditor: public class CustomPropertyEditor implements PropertyEditorRegistrar { @Override public void registerCustomEditors(PropertyEditorRegistry registry) { registry.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"),true)); } } 配置如下: <!-- 注册属性编辑器 --> <bean id="customPropertyEditor" class="cn.itcast.ssm.propertyeditor.CustomPropertyEditor"></bean> <!-- 自定义webBinder --> <bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="propertyEditorRegistrars"> <list> <ref bean="customPropertyEditor"/> </list> </property> </bean> <!--注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer" ref="customBinder"></property> </bean> Converter 自定义Converter public class CustomDateConverter implements Converter<String, Date> { @Override public Date convert(String source) { try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); return simpleDateFormat.parse(source); } catch (Exception e) { e.printStackTrace(); } return null; } } 配置方式1 <!--注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer" ref="customBinder"></property> </bean> <!-- 自定义webBinder --> <bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="conversionService" ref="conversionService" /> </bean> <!-- conversionService --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!-- 转换器 --> <property name="converters"> <list> <bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/> </list> </property> </bean> 配置方式2 <mvc:annotation-driven conversion-service="conversionService"> </mvc:annotation-driven> <!-- conversionService --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!-- 转换器 --> <property name="converters"> <list> <bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/> </list> </property> </bean>
包装对象定义如下: Public class QueryVo { private Items items; } 页面定义: <input type="text" name="items.name" /> <input type="text" name="items.price" /> ModelAttribute @ModelAttribute作用如下: 1、绑定请求参数到pojo并且暴露为模型数据传到视图页面 此方法可实现数据回显效果。 // 商品修改提交 @RequestMapping("/editItemSubmit") public String editItemSubmit(@ModelAttribute("item") Items items,Model model) 页面: <tr> <td>商品名称</td> <td><input type="text" name="name" value="${item.name }"/></td> </tr> <tr> <td>商品价格</td> <td><input type="text" name="price" value="${item.price }"/></td> </tr> list List List中存放对象,并将定义的List放在包装类中,action使用包装对象接收。 List中对象: 成绩对象 Public class QueryVo { Private List<Items> itemList;//订单明细 //get/set方法.. } 包装类中定义List对象,并添加get/set方法如下: 页面: <tr> <td> <input type="text" name=" itemList[0].id" value="${item.id}"/> </td> <td> <input type="text" name=" itemList[0].name" value="${item.name }"/> </td> <td> <input type="text" name=" itemList[0].price" value="${item.price}"/> </td> </tr> <tr> <td> <input type="text" name=" itemList[1].id" value="${item.id}"/> </td> <td> <input type="text" name=" itemList[1].name" value="${item.name }"/> </td> <td> <input type="text" name=" itemList[1].price" value="${item.price}"/> </td> </tr> Contrller方法定义如下: public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{ System.out.println(queryVo.getItemList()); }
对于get请求中文参数出现乱码解决方法有两个: 修改tomcat配置文件添加编码与工程编码一致,如下: <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/> 另外一种方法对参数进行重新编码: String userName new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8") ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码