写的很差,有兴趣就跑跑项目吧,在附件中,文章可看性很低。
环境:win7 MyEclipse10 jdk1.6 tomcat7 SpringMVC2.5 MySQL
目标:CRUD
从前文http://340413629-qq-com.iteye.com/blog/2032793修改而来,目的是使用增加数据库的操作
加入jdbcUtil类封装取得连接和释放资源的操作
package cn.zinue100.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public final class JdbcUtils { private static final String url = "jdbc:mysql://localhost:3306/test"; private static final String username = "root"; private static final String password = "root"; private JdbcUtils() { } static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } public static void free(ResultSet resultSet, Statement statement, Connection connection) { try { if (resultSet != null) resultSet.close(); } catch (SQLException e) { throw new ExceptionInInitializerError(e); } finally { try { if (statement != null) statement.close(); } catch (SQLException e) { throw new ExceptionInInitializerError(e); } finally { try { if (connection != null) connection.close(); } catch (SQLException e) { throw new ExceptionInInitializerError(e); } } } } }
这个类指使用了释放资源free方法,取得链接是通过配置连接池实现的在web-main.xml中多了如下配置,连接池是什么就不赘述了,这里没有配置最大连接数等等,只是做个样子
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
另外还多了<bean id="userDaoImpl" class="cn.zinue100.dao.jdbcImpl.UserDaoImpl" />这一配置
这是spring ioc 控制翻转,也叫依赖注入的体现,配置好这个bean之后在userConrol中加入变量
@Resource private UserDao userDao;
生成getter setter方法之后容器自动new dao
多加了三个jar包,在附件中有:
mysql-connector-java-5.1.27-bin.jar
commons-dbcp.jar
commons-pool.jar
其他的就不赘述了
主要是想学springmvc的跳转,我自己来总结一下:
贴出UserControl代买
package cn.zinue100.controller; import java.io.File; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import org.apache.commons.io.FileUtils; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import cn.zinue100.dao.UserDao; import cn.zinue100.vo.User; @Controller @RequestMapping(value = "/user") @SessionAttributes(value = "loginUser") public class UserController { @Resource private UserDao userDao; private User user; Map<String, User> users = new LinkedHashMap<String, User>(); @RequestMapping(value = "/list.htm") public String list(Model model) { init(model, null); return "user/userlist"; } @RequestMapping(value = "/add.htm", method = RequestMethod.GET) public String add(Model model) { model.addAttribute(new User()); return "user/adduser"; } @RequestMapping(value = "/add.htm", method = RequestMethod.POST) public String add(@Valid User user, BindingResult binding, Model model) { if (binding.hasErrors()) return "user/adduser"; userDao.addUser(user); init(model, user); return "redirect:/user/list.htm"; } @RequestMapping(value = "/delete/{username}.htm", method = RequestMethod.GET) public String delete(@PathVariable String username) { user=new User(); user.setUsername(username); userDao.deleteUser(user); return "redirect:/user/list.htm"; } @RequestMapping(value = "/update/{username}.htm", method = RequestMethod.GET) public String update(@PathVariable String username, Model model) { User user = userDao.getUserByName(username); model.addAttribute("user", user); return "user/updateuser"; } @RequestMapping(value = "/update/{username}.htm", method = RequestMethod.POST) public String update(@PathVariable String username, @Valid User user,BindingResult br) { if (br.hasErrors()) return "/update/{username}.htm"; userDao.updateUser(user); return "redirect:/user/list.htm"; } @ResponseBody @RequestMapping(value = "/{username}.htm", params = "json") public User showJson(@PathVariable String username, Model model) { System.out.println("username:" + username); return null; } @RequestMapping(value = "/login.htm", method = RequestMethod.GET) public String login() { return "/user/login"; } @RequestMapping(value = "/login.htm", method = RequestMethod.POST) public String login(String username, String password, Model model) { User user = userDao.getUserByName(username); if (user == null || user.getUsername() == null) throw new RuntimeException("用户名不存在!"); if (user.getPassword() == null || !user.getPassword().equals(password)) throw new RuntimeException("密码不正确"); model.addAttribute("loginUser", user); return "redirect:/user/list.htm"; } @ExceptionHandler(value = { RuntimeException.class }) public String handlerException(Exception ex, HttpServletRequest req) { System.out.println("UserController.handlerException invok..."); req.setAttribute("ex", ex);// 把异常放入request请求中 return "error";// 转到error页面 } @RequestMapping(value = "/redir.htm") public String redir(Model model, RedirectAttributes ra) { System.out.println("UserController.redir invok..."); // model.addAttribute("movie", "海贼王");//使用这种方式在重定向是传递不了的 ra.addFlashAttribute("movie", "海贼王");// 使用这种可以 return "redirect:/user/list.htm"; } @RequestMapping(value = "upload.htm", method = RequestMethod.GET) public String uploadPhoto() { System.out.println("UserController.uploadPhoto invok..."); return "user/upload"; } @RequestMapping(value = "upload.htm", method = RequestMethod.POST) public String uploadPhoto(MultipartFile photo, Model model, HttpServletRequest req) { System.out.println("UserController.init invok..."); System.out.println(photo.getContentType()); System.out.println(photo.getName()); System.out.println(photo.getOriginalFilename()); String realpath = req.getSession().getServletContext() .getRealPath("/upload/"); System.out.println(realpath); try { FileUtils.copyInputStreamToFile(photo.getInputStream(), new File( realpath + "/" + photo.getOriginalFilename())); } catch (IOException e) { e.printStackTrace(); } model.addAttribute("message", "上传成功"); return "user/upload"; } @RequestMapping(value = "uploads.htm", method = RequestMethod.POST) public String uploadPhoto( @RequestParam(required = false) MultipartFile[] photos, Model model, HttpServletRequest req) { System.out.println("UserController.init invok..."); String realpath = req.getSession().getServletContext() .getRealPath("/upload/"); try { for (MultipartFile photo : photos) { if (photo.isEmpty()) continue; FileUtils.copyInputStreamToFile(photo.getInputStream(), new File(realpath + "/" + photo.getOriginalFilename())); } } catch (IOException e) { e.printStackTrace(); } model.addAttribute("message", "上传成功"); return "user/upload"; } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } private void init(Model model, User user) { System.out.println("UserController.init invok..."); Map<String, User> users = userDao.getUsers(); model.addAttribute("users", users); } }
@RequestMapping(value = "/user")
就是说这个Control所有action都用user前缀
也就是说在一个静态页面href="user/login.htm就可以进这个action
@RequestMapping(value = "/login.htm", method = RequestMethod.GET) public String login() { return "/user/login"; }
这个方法是从静态页面跳转的login页面的,我的jsp在user包下,名字叫login.jsp。很显然springmvc把jsp页面映射成别的了,只要名字匹配就可以跳转
在jsp页面有action="login.htm"于是跳转到了以下方法
@RequestMapping(value = "/login.htm", method = RequestMethod.POST) public String login(String username, String password, Model model) { User user = userDao.getUserByName(username); if (user == null || user.getUsername() == null) throw new RuntimeException("用户名不存在!"); if (user.getPassword() == null || !user.getPassword().equals(password)) throw new RuntimeException("密码不正确"); model.addAttribute("loginUser", user); return "redirect:/user/list.htm"; }
单这个方法和前一个名字一样只是参数不同,那springmvc是怎么找过来对的呢??我觉得是根据参数和jsp文档中input的name去匹配
username:<input type="text" name="username"/><sf:errors path="username"/><br/> password:<input type="password" name="password"/><sf:errors path="password"/><br/>
第三个参数model是什么呢,model在org.springframework.ui.Model;包中,所以我觉得model就是封装了页面信息,model放在哪里??我觉得应该在session中
model.addAttribute("loginUser", user); return "redirect:/user/list.htm";
第二句代码转发到以htm结尾的url去了,很显然验证完用户名密码之后,要去初始化一览页面的信息,将跳转到control类的另一个方法
第一句往session中放了一个值,这个值在一览页面时这样显示的${loginUser.username}也就是说直接变量名key值,然后取属性,真是方便,目前不知道实现机制是什么,jstl还是ognl???
刚才说到跳转到list.htm,那贴出这个方法
@RequestMapping(value = "/list.htm") public String list(Model model) { init(model, null); return "user/userlist"; }初始化一览页面在很多地方用到,所以封装起来
private void init(Model model, User user) { Map<String, User> users = userDao.getUsers(); model.addAttribute("users", users); }我本来getUsers返回的是List,可是spring不允许我往model中放进list,必须放map。从这里可以看出model的实现机制 看一下我写的userlist页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@page import="cn.zinue100.vo.User"%> <%@page import="java.util.Map.Entry"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>userlist</title> </head> <body> <a href="add.htm">Add</a> ${loginUser.username } ${movie } <br /> <table border="1"> <% Map<String, User> users = (Map<String, User>) request .getAttribute("users"); if (users != null) { for (User user : users.values()) { %> <tr> <td><%=user%></td> <td> <a href="update/<%=user.getUsername()%>.htm">修改</a> </td> <td> <a href="delete/<%=user.getUsername()%>.htm">删除</a> </td> </tr> <% } } %> </table> <a href="login.htm">退出</a> <br /> </body> </html>
另起一个话头
码农首先关心的是,怎么从control跳转到jsp,怎么从jsp跳转到control,怎么传值
从control跳转到jsp刚才说过了,在control中返回值是个字符串,把jsp文件名去掉后缀.jsp,前面加路径,放进这个字符串就行
jsp跳转到control,在action中配置,如果没配置,那就是跟自己文件名相同的action
那怎么传值呢??
来看从一览页面去更新页面这个方法
@RequestMapping(value = "/update/{username}.htm", method = RequestMethod.GET) public String update(@PathVariable String username, Model model) { User user = userDao.getUserByName(username); model.addAttribute("user", user); return "user/updateuser"; }
这是get方法的传值,直接在url上拼,因为注解了@PathVariable,所以取得时候直接用名称取,那post方法呢???
@RequestMapping(value = "/update/{username}.htm", method = RequestMethod.POST) public String update(@PathVariable String username, @Valid User user,BindingResult br) { if (br.hasErrors()) return "/update/{username}.htm"; userDao.updateUser(user); return "redirect:/user/list.htm"; }
我没有把user这个对象传递过来,那spring怎么知道的??因为这是我在类中定义的user变量,不知道这种方法是不是正确的。
结论是从control往页面传递值是放进model中,页面根据属性名取值,jsp往control传值是直接映射进方法参数中的
其他代码在附件中,lib包太大,我只把新加的放进lib包单独放上来
其他包去前一篇博文中找吧