赞
踩
web容器(tomcat:web应用服务器软件)中可以有多个servlet对象
每个Servlet在Tomcat容器中只有一个实例,它是线程不安全的
- 1. 新建项目 - 新建模块
- 2. 在模块中添加web
- 3. 创建artifact - 部署包
- 4. lib - artifact
- 先有artifact,后来才添加的mysql.jar。此时,这个jar包并没有添加到部署包中
- 那么在projectSettings中有一个Problems中会有提示的,我们点击fix选择add to...
- 另外,我们也可以直接把lib文件夹直接新建在WEB-INF下。
- 这样不好的地方是这个lib只能是当前这个moudle独享。如果有第二个moudle我们需要再次重复的新建lib。
- 5. 在部署的时候,修改application Context。然后再回到server选项卡,检查URL的值。
- URL的值指的是tomcat启动完成后自动打开你指定的浏览器,然后默认访问的网址。
- 启动后,报错404.404意味着找不到指定的资源。
- 如果我们的网址是:http://localhost:8080/pro01/ , 那么表明我们默认访问的是index.html.
- 我们可以通过<welcome-file-list>标签进行设置欢迎页(在tomcat的web.xml中设置,或者在自己项目的web.xml中设置)
- 6. 405问题。当前请求的方法不支持。比如,我们表单method=post , 那么Servlet必须对应doPost。否则报405错误。
- 7. 空指针或者是NumberFormatException 。因为有价格和库存。如果价格取不到,结果你想对null进行Integer.parseInt()就会报错。错误的原因大部分是因为 name="price"此处写错了,结果在Servlet端还是使用request.getParameter("price")去获取。
- 8. <url-pattern>中以斜杠开头
- 9.404:找不到对应的资源
快捷键:变量名.soutv
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <form action="add" method="post">
- 名称:<input type="text" name="fname" /><br>
- 价格:<input type="text" name="price" /><br>
- 库存:<input type="text" name="fcount" /><br>
- 备注:<input type="text" name="remark" /><br>
- <input type="submit" value="添加"/>
- </form>
- </body>
- </html>
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
- version="4.0">
- <servlet>
- <servlet-name>AddServlet</servlet-name>
- <servlet-class>com.atguigu.servlets.AddServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>AddServlet</servlet-name>
- <url-pattern>/add</url-pattern>
- </servlet-mapping>
- <!--
- 1.用户发请求,action = add
- 2.在项目中的web.xml中找到url-pattern = /add -> 第12行
- 3.找第11行的servlet-name = AddServlet
- 4.找和servlet-mapping中的servlet-name一致的servlet,找到第7行
- 5.找第8行的servlet-class -> com.atguigu.servlets.AddServlet
- 6.用户发送的是post请求(method = post),因此tomcat会执行AddServlet中的doPost方法
- -->
- </web-app>
- public class AddServlet extends HttpServlet {
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String fname = request.getParameter("fname");
- String priceStr = request.getParameter("price");
- Integer price = Integer.parseInt(priceStr);
- String fcountStr = request.getParameter("fcount");
- Integer fcount = Integer.parseInt(fcountStr);
- String remark = request.getParameter("remark");
-
- FruitDAO fruitDAO = new FruitDAOImpl();
- boolean flag = fruitDAO.addFruit(new Fruit(0,fname,price,fcount,remark));
-
- System.out.println(flag ? "添加成功!":"添加失败!");
-
- }
- }
- public abstract class BaseDAO<T> {
- public final String DRIVER = "com.mysql.jdbc.Driver" ;
- public final String URL = "jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&characterEncoding=utf-8&useSSL=false";
- public final String USER = "root";
- public final String PWD = "123456";
-
- protected Connection conn ;
- protected PreparedStatement psmt ;
- protected ResultSet rs ;
-
- //T的Class对象
- private Class entityClass ;
-
- public BaseDAO(){
- //getClass() 获取Class对象,当前我们执行的是new FruitDAOImpl() , 创建的是FruitDAOImpl的实例
- //那么子类构造方法内部首先会调用父类(BaseDAO)的无参构造方法
- //因此此处的getClass()会被执行,但是getClass获取的是FruitDAOImpl的Class
- //所以getGenericSuperclass()获取到的是BaseDAO的Class
- Type genericType = getClass().getGenericSuperclass();
- //ParameterizedType 参数化类型
- Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
- //获取到的<T>中的T的真实的类型
- Type actualType = actualTypeArguments[0];
- try {
- entityClass = Class.forName(actualType.getTypeName());
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- //获取连接
- protected Connection getConn(){
- try {
- //1.加载驱动
- Class.forName(DRIVER);
- //2.通过驱动管理器获取连接对象
- return DriverManager.getConnection(URL, USER, PWD);
- } catch (ClassNotFoundException | SQLException e) {
- e.printStackTrace();
- }
- return null ;
- }
-
- protected void close(ResultSet rs , PreparedStatement psmt , Connection conn){
- try {
- if (rs != null) {
- rs.close();
- }
- if(psmt!=null){
- psmt.close();
- }
- if(conn!=null && !conn.isClosed()){
- conn.close();
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- //给sql语句中的占位符传值
- private void setParams(PreparedStatement psmt , Object... params) throws SQLException {
- if(params!=null && params.length>0){
- for (int i = 0; i < params.length; i++) {
- psmt.setObject(i+1,params[i]);
- }
- }
- }
-
- //执行更新,返回影响行数
- protected int executeUpdate(String sql , Object... params){
- boolean insertFlag = false ;
- insertFlag = sql.trim().toUpperCase().startsWith("INSERT");
- try {
- conn = getConn();
- if(insertFlag){
- psmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
- }else {
- psmt = conn.prepareStatement(sql);
- }
- setParams(psmt,params);
- int count = psmt.executeUpdate() ;
-
- if(insertFlag){
- rs = psmt.getGeneratedKeys();
- if(rs.next()){
- return ((Long)rs.getLong(1)).intValue();
- }
- }
-
- return count ;
- } catch (SQLException e) {
- e.printStackTrace();
- }finally {
- close(rs,psmt,conn);
- }
- return 0;
- }
-
- //通过反射技术给obj对象的property属性赋propertyValue值
- private void setValue(Object obj , String property , Object propertyValue){
- Class clazz = obj.getClass();
- try {
- //获取property这个字符串对应的属性名 , 比如 "fid" 去找 obj对象中的 fid 属性
- Field field = clazz.getDeclaredField(property);
- if(field!=null){
- field.setAccessible(true);
- field.set(obj,propertyValue);
- }
- } catch (NoSuchFieldException | IllegalAccessException e) {
- e.printStackTrace();
- }
- }
-
- //执行复杂查询,返回例如统计结果
- protected Object[] executeComplexQuery(String sql , Object... params){
- try {
- conn = getConn() ;
- psmt = conn.prepareStatement(sql);
- setParams(psmt,params);
- rs = psmt.executeQuery();
-
- //通过rs可以获取结果集的元数据
- //元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
-
- ResultSetMetaData rsmd = rs.getMetaData();
- //获取结果集的列数
- int columnCount = rsmd.getColumnCount();
- Object[] columnValueArr = new Object[columnCount];
- //6.解析rs
- if(rs.next()){
- for(int i = 0 ; i<columnCount;i++){
- Object columnValue = rs.getObject(i+1); //33 苹果 5
- columnValueArr[i]=columnValue;
- }
- return columnValueArr ;
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- close(rs,psmt,conn);
- }
- return null ;
- }
-
- //执行查询,返回单个实体对象
- protected T load(String sql , Object... params){
- try {
- conn = getConn() ;
- psmt = conn.prepareStatement(sql);
- setParams(psmt,params);
- rs = psmt.executeQuery();
-
- //通过rs可以获取结果集的元数据
- //元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
-
- ResultSetMetaData rsmd = rs.getMetaData();
- //获取结果集的列数
- int columnCount = rsmd.getColumnCount();
- //6.解析rs
- if(rs.next()){
- T entity = (T)entityClass.newInstance();
-
- for(int i = 0 ; i<columnCount;i++){
- String columnName = rsmd.getColumnName(i+1); //fid fname price
- Object columnValue = rs.getObject(i+1); //33 苹果 5
- setValue(entity,columnName,columnValue);
- }
- return entity ;
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } finally {
- close(rs,psmt,conn);
- }
- return null ;
- }
-
- //执行查询,返回List
- protected List<T> executeQuery(String sql , Object... params){
- List<T> list = new ArrayList<>();
- try {
- conn = getConn() ;
- psmt = conn.prepareStatement(sql);
- setParams(psmt,params);
- rs = psmt.executeQuery();
-
- //通过rs可以获取结果集的元数据
- //元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
-
- ResultSetMetaData rsmd = rs.getMetaData();
- //获取结果集的列数
- int columnCount = rsmd.getColumnCount();
- //6.解析rs
- while(rs.next()){
- T entity = (T)entityClass.newInstance();
-
- for(int i = 0 ; i<columnCount;i++){
- String columnName = rsmd.getColumnName(i+1); //fid fname price
- Object columnValue = rs.getObject(i+1); //33 苹果 5
- setValue(entity,columnName,columnValue);
- }
- list.add(entity);
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } finally {
- close(rs,psmt,conn);
- }
- return list ;
- }
- }
- public interface FruitDAO {
- //查询库存列表
- List<Fruit> getFruitList();
-
- //新增库存
- boolean addFruit(Fruit fruit);
-
- //修改库存
- boolean updateFruit(Fruit fruit);
-
- //根据名称查询特定库存
- Fruit getFruitByFname(String fname);
-
- //删除特定库存记录
- boolean delFruit(String fname);
- }
- public class FruitDAOImpl extends BaseDAO<Fruit> implements FruitDAO {
- //查询库存列表
- @Override
- public List<Fruit> getFruitList() {
- return super.executeQuery("select * from t_fruit");
- }
-
- //新增库存
- @Override
- public boolean addFruit(Fruit fruit) {
- String sql = "insert into t_fruit values(0,?,?,?,?)";
- int count = super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark()) ;
- //insert语句返回的是自增列的值,而不是影响行数
- //System.out.prin tln(count);
- return count>0;
- }
-
- //修改库存
- @Override
- public boolean updateFruit(Fruit fruit) {
- String sql = "update t_fruit set fcount = ? where fid = ? " ;
- return super.executeUpdate(sql,fruit.getFcount(),fruit.getFid())>0;
- }
-
- //根据名称查询特定库存
- @Override
- public Fruit getFruitByFname(String fname) {
- return super.load("select * from t_fruit where fname like ? ",fname);
- }
-
- //删除特定库存记录
- @Override
- public boolean delFruit(String fname) {
- String sql = "delete from t_fruit where fname like ? " ;
- return super.executeUpdate(sql,fname)>0;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。