ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring MVC2 - 6 - (2). SpringMVC2에 아두이노와 시리얼 통신(버튼)
    JAVA/웹 프로그래밍 - Spring 2020. 12. 22. 14:48

    앞의 내용과 이어지는 부분이 있다.

    designatedroom87.tistory.com/345

     

    Spring MVC2 - 6 - (1). SpringMVC2에 아두이노와 시리얼 통신

    아래의 내용에 이어지는 내용이다. designatedroom87.tistory.com/344?category=909022 El index.html index.htm i.." data-og-host="designatedroom87.tistory.com" data-og-source-url="https://designatedroom8..

    designatedroom87.tistory.com

     

    위의 내용에서는 아두이노가 데이터가 전송하면 java가 1또는 0 데이터를 받아서 웹 서버에서 이를 처리했다.

    ( 추가적으로 웹 클라이언트가 웹 서버에게 요청해서 데이터를 학인하는 작업까지 했다. )

    기존에 우리가 앞에서 한 내용은 데이터를 인위적으로 데이터를 자바에게 주었다.

    이번에는 아두이노에서 버튼을 누를 것이다. 버튼이 눌리면, 자바에서 버튼이 눌렸는지 확인을 하고, 
    확인을 하면 웹 서버에서는 DB에 접속해서 숫자를 증가시킬 것이다. ( SQL문의 업데이트 구문 이용 )

     

     

    가장 먼저 해야할 작업은 버튼과 아두이노를 먼저 연결해보자.

    빨간선은 아두이노의 GND에 연결하고, 파란선은 아두이노의 11번 핀에 연결한다.

     

    버튼은 아두이노의 11번핀과 GND에 연결하고 풀업 저항으로 연결한다.

    아래를 참고하자. 

    designatedroom87.tistory.com/219?category=898090

     

    Pull down & Pull up 저항

    풀다운 저항 풀다운 저항은 출력 지점을 기준으로 저항이 아래에 위치하면 풀다운 저항이다. 사용목적은 플로팅 상태 방지이다. 버튼이 OFF이면 출력값은 0이다. 버튼이 ON이면 출력값은 1이다.

    designatedroom87.tistory.com

    아두이노 소스 파일1

    하드웨어의 연결이 제대로 되었는지 아래의 프로그램을 통해 알아보자.

    아래의 프로그램에서 시리얼 모니터를 통해서 버튼의 눌림을 확인해보자.

    시리얼 모니터 칸은 맨 우측에 있다.

    // 아두이노의 버튼이 눌리는지 확인하는 소스
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      
      pinMode(11,INPUT_PULLUP);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      Serial.println(digitalRead(11));	// 데이터를 외부로 보내는 부분
    
      delay(200);
    }

    위의 결과에 대한 창은 아래와 같다.

     

     

    위 프로그램을 통해 버튼이 제대로 동작한다면, 버튼이 눌렸을 때, 외부로 데이터 1을 전송하는 프로그램을 만들어보자.

    이 프로그램 또한 시리얼 모니터를 통해서 버튼이 눌렸을 때만 1이 출력됨을 확인하자.

    아두이노 소스 파일2

    //  버튼이 눌려졌을 때, 외부로 데이터 1을 전송하는 프로그램
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      
      pinMode(11,INPUT_PULLUP);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      //  버튼이 눌리면
      if (digitalRead(11) == LOW)
      {
        Serial.print(1);  //  데이터를 보내는 작업
      }
      delay(200);
    }

     

    결과는 아래와 같다.

     

     

    위의 아두이노 소스 파일2가 아두이노에 업로드가 되면, 아두이노로 해야할 작업은 모두 끝났다.

    아두이노에서 전송한 데이터를 자바에서 수신해보자.

     ArduinoToSerial 프로젝트의 SerialRead.java의 run메소드에서

    System.out.println("serial read:"+s); 문장만 남기고 주석처리를 하자.

    아니면, 기존의 run메소드를 주석처리하고 아래의 메소드를 복사해서 써도 된다.

    나중에 주석처리를 제거할 것이다.

    아래는 주석처리를 하고난 후의 SerialRead.java 파일의 내용

    아래는 주석된 문장을 제거하고 난 후의 run메소드

    @Override
    	public void run() 
    	{
    		byte[] buffer=new byte[1024];
    		int len=-1;
    		
    		try {
    			while((len=in.read(buffer))>-1) {
    				String s=new String(buffer,0,len);
    				if(len!=0) { 
    					System.out.println("serial read:"+s);
    				}
    			}
    		} catch (IOException e) {e.printStackTrace();}
    	}

     

    자바에서 이를 수신해보자. Main.java를 실행하고, 버튼을 눌러보자.

    버튼이 눌리면 아래와 같이 콘솔 화면 창에 1이 뜬다.

     

     

    외부로 전송된 데이터는 자바에서 수신한다.
    수신이 되었을 때, URL을 통해 웹 서버에 데이터 전송한다.

    run메소드의 주석을 제거하자.

     

    그리고 위의 기존의 문장을 주석처리하고

    String targetURL = "http://localhost:9090/serialdb?data="+s;

    위의 문장을 추가하자.

    아래는 SerialRead.java의 전체 내용이다.

    SerialRead.java

    더보기
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class SerialRead implements Runnable{
    	
    	InputStream in;
    	
    	public SerialRead(InputStream in){this.in=in;}
    	
    	@Override
    	public void run() 
    	{
    		byte[] buffer=new byte[1024];
    		int len=-1;
    		
    		try {
    			while((len=in.read(buffer))>-1) {
    				String s=new String(buffer,0,len);
    				if(len!=0) { 
    					System.out.println("serial read:"+s);
    					
    					//	java->web server접속을 url활용
    					//String targetURL = "http://localhost:9090/serialdata?data="+s;
    					String targetURL = "http://localhost:9090/serialdb?data="+s;
    					
    					System.out.println(targetURL);
    					
    					URL url = new URL(targetURL);
    					try {
    					HttpURLConnection conn=
    							(HttpURLConnection) url.openConnection();
    					
    					BufferedReader br=
    							new BufferedReader(
    									new InputStreamReader(
    											conn.getInputStream()));
    					String temp=null;
    					while((temp=br.readLine())!=null) { }
    					conn.disconnect();
    					br.close();
    					}catch(Exception e) {}
    				}
    			}
    		} catch (IOException e) {	e.printStackTrace();	}
    	}
    }

     

     

    그리고 나머지는 springmvc2 프로젝트에서 처리 하면 된다.

    springmvc2 프로젝트에 와서 처음에 할 작업은 웹 서버 URL을 통해 데이터 수신 확인하는 것이다.

     

    1. DB제작

    create table num(count int);
    insert into num values(1);
    select * from num
    update num set count=count+1

    위의 SQL문을 활용해서 DB에 접근할 메소드들을 만들 것이다.

    우선, 위의 문장들을 각 각 실행해서 SQL에 오류가 없는지 확인을 해보자.

    위의 SQL문의 맨 위에서 첫 문장과 두 번째 문장만 실행해서 테이블을 생성하고 1을 저장하자.

     

     

    2. spring을 활용한 mybatis DB연결

    pom.xml 설정(라이브러리 추가) mybatis, mybatis-spring, HikariCP(dataSource- Connection)

    아래의 문장을 복사해서 pom.xml에 추가하면 된다.

    그러나, 우리는 이미 추가가 되어있다.

    밑에 있는 내용을 복사하지 말고, pom.xml 전체 내용을 밑에 준비해뒀다.

    <!-- mybatis -->
    <!-- mybatis 프레임워크 사용하기 위해 -->
    		<dependency>
    		    <groupId>org.mybatis</groupId>
    		    <artifactId>mybatis</artifactId>
    		    <version>3.5.5</version>
    		</dependency>
    		<!-- mybatis와 spring 연동하기 위해 -->
    		<dependency>
    		    <groupId>org.mybatis</groupId>
    		    <artifactId>mybatis-spring</artifactId>
    		    <version>2.0.5</version>
    		</dependency>
    <!-- jdbc Connection Pool -->
    		<dependency>
    	        <groupId>com.zaxxer</groupId>
    	        <artifactId>HikariCP</artifactId>
    	        <version>3.4.5</version>
    	    </dependency>

     

    pom.xml 의 전체 내용

    더보기
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.iot</groupId>
      <artifactId>springmvc2</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      
       <properties>
    		<java-version>1.8</java-version>
    		<maven.compiler.source>1.8</maven.compiler.source>
    		<maven.compiler.target>1.8</maven.compiler.target>
    		<org.springframework-version>5.2.9.RELEASE</org.springframework-version>
    		<org.aspectj-version>1.6.10</org.aspectj-version>
    		<org.slf4j-version>1.6.6</org.slf4j-version>
    	</properties>
    	
    	<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-api -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-api</artifactId>
        <version>9.0.39</version>
    </dependency>
    
    
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.2.9.RELEASE</version>
        <scope>test</scope>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    
    <!-- mybatis -->
    <!-- mybatis 프레임워크 사용하기 위해 -->
    		<dependency>
    		    <groupId>org.mybatis</groupId>
    		    <artifactId>mybatis</artifactId>
    		    <version>3.5.5</version>
    		</dependency>
    		<!-- mybatis와 spring 연동하기 위해 -->
    		<dependency>
    		    <groupId>org.mybatis</groupId>
    		    <artifactId>mybatis-spring</artifactId>
    		    <version>2.0.5</version>
    		</dependency>
    <!-- jdbc Connection Pool -->
    		<dependency>
    	        <groupId>com.zaxxer</groupId>
    	        <artifactId>HikariCP</artifactId>
    	        <version>3.4.5</version>
    	    </dependency>
    
    <!-- Logging -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-api</artifactId>
    			<version>${org.slf4j-version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>jcl-over-slf4j</artifactId>
    			<version>${org.slf4j-version}</version>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-log4j12</artifactId>
    			<version>${org.slf4j-version}</version>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>log4j</groupId>
    			<artifactId>log4j</artifactId>
    			<version>1.2.15</version>
    			<exclusions>
    				<exclusion>
    					<groupId>javax.mail</groupId>
    					<artifactId>mail</artifactId>
    				</exclusion>
    				<exclusion>
    					<groupId>javax.jms</groupId>
    					<artifactId>jms</artifactId>
    				</exclusion>
    				<exclusion>
    					<groupId>com.sun.jdmk</groupId>
    					<artifactId>jmxtools</artifactId>
    				</exclusion>
    				<exclusion>
    					<groupId>com.sun.jmx</groupId>
    					<artifactId>jmxri</artifactId>
    				</exclusion>
    			</exclusions>
    			<scope>runtime</scope>
    		</dependency>
    		<!-- Spring -->
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context</artifactId>
    			<version>${org.springframework-version}</version>	<!-- 위에서 받은 버전을 가지고 올 수 있다. -->
    			<exclusions>
    				<!-- Exclude Commons Logging in favor of SLF4j -->
    				<exclusion>
    					<groupId>commons-logging</groupId>
    					<artifactId>commons-logging</artifactId>
    				 </exclusion>
    			</exclusions>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-webmvc</artifactId>
    			<version>${org.springframework-version}</version>
    		</dependency>
    				
    	</dependencies>
    </project>

     

     

    src/main/java에 db패키지를 하나 만든다. db패키지의 위치는 아래의 그림을 참고하자.

    이 db패키지에 "spring bean configuration file"을 하나 만드는데 이름은 dbconfig이다.

    dbconfig.xml 에서는 mybatis 관련 클래스 파일을 bean 설정을 한다.

    아래의 내용을 복사해서 붙이자.

    dbconfig.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:context="http://www.springframework.org/schema/context"
    	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
    	xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    
    <!-- mybaties DB 설정 -->
    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    	<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
    	<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
    	<property name="username" value="hr"></property>
    	<property name="password" value="1234"></property>
    </bean>
    
    <!-- 어노테이션을 사용하기 위한 설정 -->
    <context:component-scan base-package="db" />
    <mybatis-spring:scan base-package="db" />
    
    <!--DB연결에 필요한 내용은 dataSource에 있다. 
    	dataSource는 DriverManager에서 만들었는데, 이번에는 다른 경로를 통해 생성한다.
    	DB datasource bean 생성
    -->
    <bean id="ds" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    	<constructor-arg ref="hikariConfig"></constructor-arg>
    </bean>
    
    <!--mybaties 사용 bean 생성(SQL문법에 대한 부분)-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    	<property name="dataSource" ref="ds"></property>
    </bean>
    
    </beans>

     

     

    db패키지에 NumInterface라는 인터페이스를 만든다.

    db인터페이스는 4가지 작업인 입력,출력,삭제,수정을 하는데, 현재의 DB에서는 update(수정)와 select(출력)만 수행한다.

    NumInterface.java

    package db;
    
    public interface NumInterface 
    {
    	public boolean update();	//	DB의 count변수를 하나 증가시키는 함수
    	public int select();		//	DB로부터 정수인 count만 받아오면 되는 함수
    }

     

     

    그리고 NumInterface를 상속하는 NumInterImple 자바 파일을 만든다.

    만약, update함수와 select함수에 붉은색 밑줄이 그어지면, @Override를 지워주도록 하자.

    NumInterImple.java

    package db;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service("num")	//	DB를 직접적으로 건드리지 않으므로 Service라 둔다.
    public class NumInterImple implements NumInterface
    {
    	@Autowired
    	private NumMapper mapper;
    	
    	@Override
    	public boolean update() {
    		return this.mapper.update() == 1 ? true : false;
    	}
    	
    	@Override
    	public int select() {
    		return this.mapper.select();
    	}
    }

     

     

    NumMapper라는 인터페이스를 만든다.

    db 인터페이스 구현(구현 파일에서는 db 인터페이스와 유사한 인터페이스 mapper가 필요)
    mapper를 이용하여 db sql문이 있는 xml파일에 접근한다.

    NumMapper.java

    package db;
    
    //	xml에 대한 인터페이스
    public interface NumMapper 
    {
    	public int update();	//	DB의 count변수를 하나 증가시키는 함수
    	public int select();	//	DB로부터 정수인 count만 받아오면 되는 함수
    }

     

     

    db패키지에 NumMapper.xml파일을 만든다.

    ( mapper.xml 파일 구현 시에  xml파일명은 mapper의 이름과 반드시 동일해야 한다. )

    NumMapper.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <!-- DB패키지 내의  NumMapper 파일을 쓰겠다는 의미-->
    <mapper namespace="db.NumMapper">
    
    <!-- select * from num -->
    <select id="select" resultType="int">
    select count from num
    </select>	
    											
    <!-- update num set count=count+1	 -->
    <update id="update" >
    update num set count=count+1
    </update>	
    					
    </mapper>

     

     

    구현된 인터페이스 클래스는 컨트롤러에서 인터페이스를 이용하여 사용한다.

    즉, IndexController.java에서 사용하면 된다. ( springmvc2패키지에 있다. )

    그러기 위해서 아래의 메소드를 하나 추가한다.

    아래의 메소드는 버튼이 눌렸을 때, db에 접속해서 count값을 1씩 증가( SQL의 update문 활용 )하는 메소드이다.

    @RequestMapping("/serialdb")
    	public void serialdb(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		
    		service.update();
    	}

     

     

    그리고, 한 가지 더 작업해야할 사항이 있다.

    오라클 드라이버를 추가해야 한다.

    WEB-INF폴더 하위에 lib폴더를 만들어서 오라클 드라이버인 ojdbc6.jar파일을 추가한다.

    아래와 같이 추가가 되면 된다.

    Main.java를 실행시키고 IndexController를 실행시킨다.

    그리고 버튼을 클릭 하고나서 db에서 버튼을 눌린 만큼 count값이 증가했는지 체크를 해보자.

    위에서 버튼이 눌렸으므로, DB에는 2가 저장되어 있으면 된다.

     

     

    마지막으로, 화면을 구현하면 된다. ( view 페이지를 만들어 db의 값을 실시간으로 가져오는 작업 )

    IndexController에 메소드를 하나 추가한다. 

    @RequestMapping("/serialdbview")
    	public ModelAndView serialdbview() {
    		//	DB 처리
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		
    		int data = service.select();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("data",data);
    		mv.setViewName("serialdbview");
    		
    		return mv;
    	}

     

     

    WEB-INF/view 폴더에 serialdbview.jsp파일을 만든다.

    serialdbview.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> 
    	<meta charset="UTF-8">
    	<title>Hello</title>
    	<link href='http://fonts.googleapis.com/css?family=Lato:100' rel='stylesheet' type='text/css'>
    	<style>
    		 body {
    			background-color: hsl(0, 60%, 65%);
    			transition: background-color 1s; 
    		} 
    
    		h1 {
    			font-family: 'Lato', sans-serif;
    			font-size: 120px;
    			font-weight: 100;
    			color: white;
    			text-align: center;
    			margin: 60px;
    		}
    
    		h1:before{
    			content: attr(class) ":";
    			font-size: 22px;
    			position: relative;
    			top: -69px;
    			left: 0;
    			text-transform: uppercase;
    		}
    </style>
    
    </head>
    <body id=b>
    <h1 id=data class="data">${data}</h1>
    <script>
       setInterval(function(){ location.href="/serialdbview" }, 3000); 
    </script>
    </body>
    </html>

     

     

    Main.java를 먼저 실행하고, 서버를 실행시키고 나서

    웹 페이지를 띄워서 주소 창에 http://localhost:9090/serialdbview 로 접속한다.

    그리고 버튼을 눌러서 확인을 해보자.

    되긴 하는데, 버튼을 몇 번 클릭하다보면 에러가 발생한다.

    발생이유는 세션을 많이 사용해서 그런듯 하다.
    세션 처리가 필요하다. SQL문과 세션에서 발생. 
    버튼이 눌릴 때마다 ApplicationContext를 계속호출해서 문제가 생긴 것 같다.
    처음 4~5번정도의 눌림은 괜찮은데 그 후에 문제가 생긴다.

    아래의 문장에서 에러가 나는 것 같다. 아래의 문장이 계속 호출 되는 것이 문제인 것 같다.

     

    아래는 현재까지의 프로젝트 파일

    ArduinoToSerial &amp; springmvc2.zip
    2.69MB

     

     

     

    심화 과정으로 만들어 볼 내용은 버튼이 눌릴 때마다 테이블의 행 증가를 구현하는 것이다.

    구현할 내용은 아래의 테이블을 먼저 보자. 

    먼저, 테이블부터 설계하자. 테이블의 이름은 test라 하자.

    idx는 시퀸스, 
    create table test(idx number(4))
    create sequence idx_seq increment by 1 start with 1 // insert
    insert into test values(idx_seq.nextval);                  // getList
    select * from test

     

    위의 네 SQL문을 실행하면, 아래와 같은 결과가 보여진다.

    시퀸스를 사용하여 행을 증가시키고 getlist를 이용하여 jsp에 출력한다.

    버튼이 눌리면 insert into test values(idx_seq.nextval); 문장을 호출한다.

    그러면, 테이블의 정보가 계속 쌓일 것이다.

    이 쌓인 정보를 프레임워크의 List에 담아 jsp에서 출력하면 된다.

    이 List를 리턴하는 함수를 getlist라 하자.

     

    변경할 지점은 우선,

    ArduinoToSerial 프로젝트의 SerialRead.java이다.

    run 메소드의 targetURL을 다음과 같이 두자.

    String targetURL = "http://localhost:9090/serialdbtable?data="+s;

     

    SerialRead.java 전체 내용

    더보기
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class SerialRead implements Runnable{
    	
    	InputStream in;
    	
    	public SerialRead(InputStream in){this.in=in;}
    	
    	@Override
    	public void run() 
    	{
    		byte[] buffer=new byte[1024];
    		int len=-1;
    		
    		try {
    			while((len=in.read(buffer))>-1) {
    				String s=new String(buffer,0,len);
    				if(len!=0) { 
    					System.out.println("serial read:"+s);
    					
    					//	java->web server접속을 url활용
    					//String targetURL = "http://localhost:9090/serialdata?data="+s;
    					//String targetURL = "http://localhost:9090/serialdb?data="+s;
    					String targetURL = "http://localhost:9090/serialdbtable?data="+s;
    					
    					System.out.println(targetURL);
    					
    					URL url = new URL(targetURL);
    					try {
    					HttpURLConnection conn=
    							(HttpURLConnection) url.openConnection();
    					
    					BufferedReader br=
    							new BufferedReader(
    									new InputStreamReader(
    											conn.getInputStream()));
    					String temp=null;
    					while((temp=br.readLine())!=null) { }
    					conn.disconnect();
    					br.close();
    					}catch(Exception e) {}
    				}
    			}
    		} catch (IOException e) {	e.printStackTrace();	}
    	}
    }

     

     

     

    그리고, IndexController에 메소드 2개를 추가한다.

    첫 번째 메소드는 버튼이 눌렸을 때, test테이블에 접근해서 sequence로 자동증가를 한다.

    두 번째 메소드는 테이블의 정보를 얻어와서 jsp에 출력한다.

    아래는 추가된 두 메소드들

    더보기
    @RequestMapping("/serialdbtable")
    	public void serialdbtable(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		
    		service.insert();
    	}
    	
    	@RequestMapping("/serialdbtableview")
    	public ModelAndView serialdbtableview() {
    		//	DB 처리
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		
    		List<Integer> list = service.getList();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("list",list);
    		mv.setViewName("serialdbtableview");
    		
    		return mv;
    	}

     

     

    src/main/java의 db패키지

    추가된 메소드는 세 번째, 네 번째이다.

    NumInterface.java

    package db;
    
    import java.util.List;
    
    public interface NumInterface 
    {
    	public boolean update();	//	DB의 count변수를 하나 증가시키는 함수
    	public int select();		//	DB로부터 정수인 count만 받아오면 되는 함수
    	public List<Integer> getList();
    	public boolean insert();
    }

     

     

    NumInterImple.java

    위의 NumInterface를 상속받는 NumInterImple클래스에도 메소드를 정의해야 한다.

    함수들의 이름에 붉은 밑줄이 생기면, @Override 키워드를 지우자.

    package db;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service("num")	//	DB를 직접적으로 건드리지 않으므로 Service라 둔다.
    public class NumInterImple implements NumInterface
    {
    	@Autowired
    	private NumMapper mapper;
    	
    	@Override
    	public boolean update() {
    		return this.mapper.update() == 1 ? true : false;
    	}
    	
    	@Override
    	public int select() {
    		return this.mapper.select();
    	}
    
    	@Override
    	public List<Integer> getList() {
    		return this.mapper.getList();
    	}
    
    	@Override
    	public boolean insert() {
    		return this.mapper.insert();
    	}
    }

     

     

    NumMapper인터페이스에도 세 번째 네 번째 메소드를 추가한다.

    NumMapper.java

    package db;
    
    import java.util.List;
    
    //	xml에 대한 인터페이스
    public interface NumMapper 
    {
    	public int update();	//	DB의 count변수를 하나 증가시키는 함수
    	public int select();	//	DB로부터 정수인 count만 받아오면 되는 함수
    	public List<Integer> getList();
    	public boolean insert();
    }

     

     

    NumMapper.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <!-- DB패키지 내의  NumMapper 파일을 쓰겠다는 의미-->
    <mapper namespace="db.NumMapper">
    
    <!-- select * from num -->
    <select id="select" resultType="int">
    select count from num
    </select>	
    											
    <!-- update num set count=count+1	 -->
    <update id="update" >
    update num set count=count+1
    </update>	
    
    <!-- public List<Member> getList(); -->		
    <select id="getList" resultType="int">
    select idx from test order by idx asc
    </select>	
    		
    <!-- public int insert(); -->
    <insert id="insert" >
    insert into test values(idx_seq.nextval)
    </insert>
    					
    </mapper>

     

     

    WEB-INF/view폴더에 serialdbtableview.jsp파일을 만든다.

    중요한 점은 ctaglib를 사용한다는 점이다.

    아래의 글에서 ctaglib에 대한 사용법을 볼 수 있고, 파일도 다운로드 할 수 있다.

    designatedroom87.tistory.com/314?category=901206

     

    taglib문법

    ${ } 태그(html에서 넘어온 문법)와 setAttribute함수(자바 문법)에서 쓸 수 있다. 새 프로젝트를 생성한다. 다이나믹 프로젝트로 만드는데 이름은 El 이라 하자. 차분히 Next를 선택하다가 아래와

    designatedroom87.tistory.com

    그렇기 때문에 WEB-INF/lib에 jstl-1.2jar 파일을 추가해야 한다.

     

     

    serialdbtableview.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
        
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <div>  
      <table border="1">
          <tr>
            <th>번호</th>
          </tr>
    
        <c:forEach var="item" items="${list}">
          <tr>
            <td>${item}</td>
          </tr>
         </c:forEach>
         
      </table>
    </div>
    <script>
       setInterval(function(){ location.href="/serialdbtableview" }, 3000); 
    </script>  
    </body>
    </html>

     

    Main.java를 먼저 실행하고 나서, 서버를 실행한 후에

    웹 페이지를 띄우고 주소 창에 http://localhost:9090/serialdbtableview 로 입력한다.

    버튼을 입력하면 테이블의 행이 추가가 되는 것을 볼 수 있다.

    그런데, 2개정도 행이 추가된 이후에 오류가 발생한다. 

     

    아래는 오류가 발생했을 때의 그림이다.

     

    현재까지의 프로젝트 파일

    ArduinoToSerial &amp; springmvc2.zip
    3.05MB

     

     

    에러를 고쳐보자.

    문제가 생기는 부분은 IndexController.java에서 IndexController 클래스의 메소드 중에서

    ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");

    위의 문장이 호출되는 부분이 문제다.

    웹에서는 쓰다가 보니까 쓸수록 자원의 한계가 있는 거 같다.

    스캔한 파일이 dbconfig인데 이파일에는 bean객체가 계속 생성된다. 

    메소드가 호출이 되면, 계속 위의 문장이 호출되서 문제가 생기는 것이다.

    그래서 메소드들 중에서 위 문장이 들어가는 부분을 모두 주석처리한다.

     

    우선 실행되는 순서에 대해서 다시 살펴보자.

    우리가 URL에서 web요청을 하면 ( 즉, 웹 페이지의 주소 창에 /serialdbview라고 검색하면 )

    web.xml이 실행이되어서 mapping이 되는데,

    dispatcher가 실행되어 org.springframework.web.servlet.DispatcherServlet 클래스가 실행이 되면

    dispatcher-servlet.xml이 실행된다. 이는 스프링이 호출한다. 

    그래서 반드시 dispatcher-servlet.xml을 만들어야 한다.

    이 dispatcher-servlet.xml이 실행되면 bean 생성이 되어 클래스 객체를 만들어 낸다.

    bean 생성 대신 어노테이션을 사용(bean 생성) 한다.

    그래서

    <bean id="index" class="springmvc2.IndexController" />

    위의 문장을 주석처리한 것이다. 즉, context:component-scan을 통해 생성한다. 

    그리고 다음과 같이 base-package에 db패키지도 추가를 한다. 

    <context:component-scan base-package="springmvc2,db" />

     

    dispatcher-servlet.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:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    
    <!-- 컨트롤러를 등록( springmvc2패키지에 컨트롤러가 있다. ) -->
     <context:component-scan base-package="springmvc2,db" />
    <!-- <bean id="index" class="springmvc2.IndexController" /> -->
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    	<property name="order" value="2" />	
    	<property name="prefix" value="/WEB-INF/view/" />
    	<property name="suffix" value=".jsp" />
    </bean>
    
    </beans>

     

     

    web.xml 에서 설정이 필요하다.

    설정이 필요한 내용은 dbconfig.xml의 내용을 실행 전에 로드를 해줘야 한다.

    즉, 실행 전에, 미리 등록하는 부분이 들어가면 된다.

    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_4_0.xsd" id="WebApp_ID" version="4.0">
      <display-name>El</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      
      <!--	<context-param>은 서블릿(dispatcher) 실행 전에  호출
      		모든 서블릿과 필터들로부터 공유된 루트경로의 스프링을 정의한다.
      		어떤 경로를 지정하고 파일을 설정한다.
      -->
      <context-param>
      	<param-name>contextConfigLocation</param-name>	<!-- 정해진 값으로, 컨텍스트 설정 위치 -->
      	<param-value>/WEB-INF/root-context.xml</param-value>
      </context-param>
      
      <!-- <listener>는 스프링 컨테이너를 만드는 역할을 한다.
      		즉, 위에서 설정된 서블릿과 필터들을 스프링 컨테이너에 만드는 역할을 한다.
      		기본 설정 파일을 로드한다.
      -->
      <listener>
      	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
       <servlet>
      	<servlet-name>dispatcher</servlet-name>
      	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      	<init-param>
      		<param-name>contextConfigLocation</param-name>
      		<param-value>
      			/WEB-INF/servlet-context.xml
      			<!-- /WEB-INF/service-context.xml -->
      		</param-value>
      	</init-param>
      	<load-on-startup>1</load-on-startup>
      </servlet>
      
      <servlet-mapping>
      	<servlet-name>dispatcher</servlet-name>
      	<url-pattern>/</url-pattern>
      </servlet-mapping>
      
    </web-app>

     

     

    그리고, xml 두 파일을 만들어야 한다.

    root-context.xml 와 servlet-context.xml 을 webapp/WEB-INF폴더에 만들어야 한다.

    두 xml파일은 spring bean configuration file로 만든다.

    servlet-context.xml 파일 내용

    servlet-context.xml의 파일 내용은 우선, db패키지에 있는 dbconfig.xml파일의 내용을 복사한다.

    그러면 dbconfig.xml파일은 더 이상 필요없다.

    그리고 변경할 부분이 있다.
    Namespaces로 가서 beans가 체크가 되어있는지 확인하자.

    dispatcher-servlet.xml에 있는 bean 내용을 옮겨온다.

    그리고 dispatcher-servlet.xml 파일은 더 이상 필요없다.

    더보기
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
    	xmlns:websocket="http://www.springframework.org/schema/websocket"
    	xsi:schemaLocation="http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd
    		http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
    		http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
    		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- mybaties DB 설정 -->
    <beans:bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    	<beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></beans:property>
    	<beans:property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe"></beans:property>
    	<beans:property name="username" value="hr"></beans:property>
    	<beans:property name="password" value="1234"></beans:property>
    </beans:bean>
    
    <!-- 어노테이션을 사용하기 위한 설정 -->
    <context:component-scan base-package="db,springmvc2" />
    <mybatis-spring:scan base-package="db" />
    <annotation-driven />
    
    <!--DB연결에 필요한 내용은 dataSource에 있다. 
    	dataSource는 DriverManager에서 만들었는데, 이번에는 다른 경로를 통해 생성한다.
    	DB datasource bean 생성
    -->
    <beans:bean id="ds" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    	<beans:constructor-arg ref="hikariConfig"></beans:constructor-arg>
    </beans:bean>
    
    <!--mybaties 사용 bean 생성(SQL문법에 대한 부분)-->
    <beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    	<beans:property name="dataSource" ref="ds"></beans:property>
    </beans:bean>
    
    <!-- resources 처리 (나중에 CSS에 대한 것들을 처리한다.) -->
    <resources location="resources" mapping="/resources/**"></resources>
    
    <!-- ViewResolver 처리 -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    	<beans:property name="order" value="2" />	
    	<beans:property name="prefix" value="/WEB-INF/view/" />
    	<beans:property name="suffix" value=".jsp" />
    </beans:bean>
    
    </beans:beans>

     

     

    root-context.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"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    
    </beans>

     

     

    springmvc2패키지의 IndexController.java로 이동하자.

    IndexController클래스에서 메소드들을 수정한다.

    메소드들 중에서 아래와 같은 문장이 들어간 부분을 주석처리하도록 한다. 

     

    IndexController.java 전체 내용

    그리고 serialdb에서 service의 update메소드와 insert메소드를 차례로 호출해서

    두 테이블에 있는 데이터를 하나씩 증가시키자. (데이터의 변화를 쉽게 알아보기 위해서이다. )

     

    더보기
    package springmvc2;
    
    import java.util.List;
    
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    import db.NumInterface;
    
    @Controller	//	자동으로 IndexController 객체 생성
    //@RequestMapping("/aaa/")	//	url에서 localhost:9090/aaa/index
    public class IndexController 
    {	
    	@Autowired						//	구현한 객체를 자동으로 주입하기 위해 쓴 키워드
    	@Qualifier(value="num")			//	NumInterImple객체를 자동으로 넣기 위해서 @Autowired를 선언
    	private NumInterface service;	//	sql 구현 객체를 사용하는 인터페이스
    	
    	@RequestMapping("/index1")
    	public String index1() {	
    		System.out.println("index.jsp실행");
    		return "index.jsp";	
    	}
    	
    	@RequestMapping("/index2")
    	public String index2() {	
    		System.out.println("/WEB-INF/index.jsp실행");
    		return "/WEB-INF/index.jsp";	
    	}
    	
    	@RequestMapping("/index3")
    	public String index3() {	
    		System.out.println("/WEB-INF/view/index.jsp실행");
    		return "/WEB-INF/view/index.jsp";	
    	}
    	
    	@RequestMapping("/index4")
    	public String index4() {	
    		System.out.println("뷰 리졸버 실행");
    		return "index4";	
    	}
    	
    	@RequestMapping("/index5")
    	public ModelAndView index5(String page, String count) {	
    		System.out.println("index5 뷰 리졸버 실행 : "+page + " " +count);
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("page",page);
    		mv.addObject("count",count);
    		mv.setViewName("index5");
    		return mv;	
    	}
    	
    	@RequestMapping("/index6")
    	public ModelAndView index6(HttpServletRequest request) {	
    		
    		String page = request.getParameter("page");
    		String count = request.getParameter("count");
    		
    		System.out.println("index6 뷰 리졸버 실행 : "+page + " " +count);
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("page",page);
    		mv.addObject("count",count);
    		mv.setViewName("index6");
    		return mv;	
    	}
    	
    	@RequestMapping("/serialdata")
    	public void serialdata(String data, HttpServletRequest request) {
    		System.out.println("web data : " +data);
    		
    		//	아두이노로부터 전송된 데이터를 활용하여 처리
    		
    		//	DB처리
    		
    		//	web jsp에 데이터를 보내는 처리
    		ServletContext app = request.getServletContext();	//	전역 저장 객체
    		app.setAttribute("data", data);
    	}
    	
    	@RequestMapping("/serial1")
    	public String serialdata1() {
    		return "arduino1";
    	}
    	
    	@RequestMapping("/serial2")
    	public ModelAndView serialdata(HttpServletRequest request) {
    		ModelAndView mv = new ModelAndView();
    		
    		ServletContext app = request.getServletContext();	//	전역 저장 객체
    		String data = (String)app.getAttribute("data");
    		
    		mv.addObject("data",data);
    		mv.setViewName("arduino2");	//	arduino페이지로 이동
    		
    		return mv;
    	}
    	
    	@RequestMapping("/serialdb")
    	public void serialdb(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		service.update();
    		service.insert();
    	}
    	
    	@RequestMapping("/serialdbview")
    	public ModelAndView serialdbview() {
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		int data = service.select();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("data",data);
    		mv.setViewName("serialdbview");
    		
    		return mv;
    	}
    	
    	@RequestMapping("/serialdbtable")
    	public void serialdbtable(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		service.insert();
    	}
    	
    	@RequestMapping("/serialdbtableview")
    	public ModelAndView serialdbtableview() {
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		List<Integer> list = service.getList();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("list",list);
    		mv.setViewName("serialdbtableview");
    		
    		return mv;
    	}
    }

     

     

    ArduinoToSerial 프로젝트에서 Main.java를 실행하기 전에, SerialRead.java에서 run메소드에서

    내용을 다음과 같이 변경하자.

     

    서버를 실행시킨다. 웹 페이지를 2개 띄우자.

    각 웹 페이지의 주소창에 http://localhost:9090/serialdbview 과

    http://localhost:9090/serialdbtableview 를 입력해서 접속해보자.

    아래는 두 웹 페이지의 내용이다. 에러없이 잘 작동한다.

     

     

    그리고  앞에서, ctaglib를 쓰기위해서 lib폴더에 jar파일을 추가했는데 이와 같이 하지 않아도 된다.

    WEB-INF/lib폴더의 jstl-1.2.jar 파일을 자워보자. 파일을 지우는 순간 에러가 난다.

    웸 페이지의 검색 창에 maven repository를 검색해서 사이트에 접속한 이후에 jstl을 검색해서 

    가장 많이 다운 받은 내용을 선택하고 버전은 1.2로 다운 받자.

    복사해서 pom.xml 에서 붙여넣자.

    붙여 넣을 내용은 아래와 같다.

    dependencies 태그의 맨 마지막에 추가하자.

    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

     

    추가한 부분은 아래와 같이 맨 마지막에 추가한다. 추가하는 동시에 라이브러리가 다운로드가 된다.

     

    아래와 같이 에러가 없어지는 것을 볼 수 있다.

     

     

    그리고 기존에는 Model없이 getList에서 Integer를 list에 담아 리턴했는데, db패키지에 Model을 하나 생성한다.

    이름은 Test.java라고 한다.

    Test.java

    package db;
    
    public class Test 
    {
    	private int idx;
    	
    	public Test() {}
    	public Test(int idx) {this.idx = idx;}
    	
    	public int getIdx() {return idx;}
    	public void setIdx(int idx) {this.idx = idx;}
    }

     

     

    NumInterface.java

    package db;
    
    import java.util.List;
    
    public interface NumInterface 
    {
    	public boolean update();	//	DB의 count변수를 하나 증가시키는 함수
    	public int select();		//	DB로부터 정수인 count만 받아오면 되는 함수
    	public List<Test> getList();
    	public boolean insert();
    }

     

     

    NumInterImple.java

    에러가 발생하는데, 나중에 없어진다.

    package db;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service("num")	//	DB를 직접적으로 건드리지 않으므로 Service라 둔다.
    public class NumInterImple implements NumInterface
    {
    	@Autowired
    	private NumMapper mapper;
    	
    	public boolean update() {
    		return this.mapper.update() == 1 ? true : false;
    	}
    	
    	public int select() {
    		return this.mapper.select();
    	}
    
    	public List<Test> getList(){
    		return this.mapper.getList();
    	}
    
    	public boolean insert() {
    		return this.mapper.insert();
    	}
    }

     

     

    NumMapper.java

    package db;
    
    import java.util.List;
    
    //	xml에 대한 인터페이스
    public interface NumMapper 
    {
    	public int update();	//	DB의 count변수를 하나 증가시키는 함수
    	public int select();	//	DB로부터 정수인 count만 받아오면 되는 함수
    	public List<Test> getList();
    	public boolean insert();
    }

     

     

    NumMapper.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <!-- DB패키지 내의  NumMapper 파일을 쓰겠다는 의미-->
    <mapper namespace="db.NumMapper">
    
    <!-- select * from num -->
    <select id="select" resultType="int">
    select count from num
    </select>	
    											
    <!-- update num set count=count+1	 -->
    <update id="update" >
    update num set count=count+1
    </update>	
    
    <!-- public List<Member> getList(); -->		
    <select id="getList" resultType="db.Test">
    select * from test order by idx asc
    </select>	
    		
    <!-- public int insert(); -->
    <insert id="insert" >
    insert into test values(idx_seq.nextval)
    </insert>
    					
    </mapper>

     

     

    springmvc2패키지의 IndexController.java

    serialdbtableview메소드를 수정하면 된다.

    더보기
    package springmvc2;
    
    import java.util.List;
    
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    import db.NumInterface;
    import db.Test;
    
    @Controller	//	자동으로 IndexController 객체 생성
    //@RequestMapping("/aaa/")	//	url에서 localhost:9090/aaa/index
    public class IndexController 
    {	
    	@Autowired				//	구현한 객체를 자동으로 주입하기 위해 쓴 키워드
    	@Qualifier(value="num")	//	NumInterImple객체를 자동으로 넣기 위해서 @Autowired를 선언
    	private NumInterface service;	//	sql 구현 객체를 사용하는 인터페이스
    	
    	@RequestMapping("/index1")
    	public String index1() {	
    		System.out.println("index.jsp실행");
    		return "index.jsp";	
    	}
    	
    	@RequestMapping("/index2")
    	public String index2() {	
    		System.out.println("/WEB-INF/index.jsp실행");
    		return "/WEB-INF/index.jsp";	
    	}
    	
    	@RequestMapping("/index3")
    	public String index3() {	
    		System.out.println("/WEB-INF/view/index.jsp실행");
    		return "/WEB-INF/view/index.jsp";	
    	}
    	
    	@RequestMapping("/index4")
    	public String index4() {	
    		System.out.println("index4 뷰 리졸버 실행");
    		return "index4";	
    	}
    	
    	@RequestMapping("/index5")
    	public ModelAndView index5(String page, String count) {	
    		System.out.println("index5 뷰 리졸버 실행 : "+page + " " +count);
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("page",page);
    		mv.addObject("count",count);
    		mv.setViewName("index5");
    		return mv;	
    	}
    	
    	@RequestMapping("/index6")
    	public ModelAndView index6(HttpServletRequest request) {	
    		
    		String page = request.getParameter("page");
    		String count = request.getParameter("count");
    		
    		System.out.println("index6 뷰 리졸버 실행 : "+page + " " +count);
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("page",page);
    		mv.addObject("count",count);
    		mv.setViewName("index6");
    		return mv;	
    	}
    	
    	@RequestMapping("/serialdata")
    	public void serialdata(String data, HttpServletRequest request) {
    		System.out.println("web data : " +data);
    		
    		//	아두이노로부터 전송된 데이터를 활용하여 처리
    		
    		//	DB처리
    		
    		//	web jsp에 데이터를 보내는 처리
    		ServletContext app = request.getServletContext();	//	전역 저장 객체
    		app.setAttribute("data", data);
    	}
    	
    	@RequestMapping("/serialdb")
    	public void serialdb(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		service.update();
    		
    		if (service.insert() == true) System.out.println("입력 성공");
    		else						System.out.println("입력 실패");
    	}
    	
    	@RequestMapping("/serial1")
    	public String serialdata1() {
    		return "arduino1";
    	}
    	
    	@RequestMapping("/serial2")
    	public ModelAndView serialdata(HttpServletRequest request) {
    		ModelAndView mv = new ModelAndView();
    		
    		ServletContext app = request.getServletContext();	//	전역 저장 객체
    		String data = (String)app.getAttribute("data");
    		
    		mv.addObject("data",data);
    		mv.setViewName("arduino2");	//	arduino페이지로 이동
    		
    		return mv;
    	}
    	
    	@RequestMapping("/serialdbview")
    	public ModelAndView serialdbview() {
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		
    		int data = service.select();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("data",data);
    		mv.setViewName("serialdbview");
    		
    		return mv;
    	}
    	/*
    	@RequestMapping("/serialdbtable")
    	public void serialdbtable(String data, HttpServletRequest request) {
    		System.out.println("web DB data : " +data);
    		
    		//	DB 처리
    	
    		//ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		//NumInterface service = context.getBean("num", db.NumInterImple.class);
    		
    		service.insert();
    	}
    	*/
    	
    	@RequestMapping("/serialdbtableview")
    	public ModelAndView serialdbtableview() {
    		//	DB 처리
    		/*
    		ApplicationContext context = new ClassPathXmlApplicationContext("db/dbconfig.xml");
    		 
    		//	num은 NumInterImple 클래스의 @Service에 있다.
    		NumInterface service = context.getBean("num", db.NumInterImple.class);
    		*/
    		
    		List<Test> list = service.getList();
    		
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("list",list);
    		mv.setViewName("serialdbtableview");
    		
    		return mv;
    	}
    }

     

     

    WEB-INF/view/serialdbview.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> 
    	<meta charset="UTF-8">
    	<title>Hello</title>
    	<link href='http://fonts.googleapis.com/css?family=Lato:100' rel='stylesheet' type='text/css'>
    	<style>
    		 body {
    			background-color: hsl(0, 60%, 65%);
    			transition: background-color 1s; 
    		} 
    
    		h1 {
    			font-family: 'Lato', sans-serif;
    			font-size: 120px;
    			font-weight: 100;
    			color: white;
    			text-align: center;
    			margin: 60px;
    		}
    
    		h1:before{
    			content: attr(class) ":";
    			font-size: 22px;
    			position: relative;
    			top: -69px;
    			left: 0;
    			text-transform: uppercase;
    		}
    </style>
    
    </head>
    <body id=b>
    <h1 id=data class="data">${data}</h1>
    <script>
       setInterval(function(){ location.href="/serialdbview" }, 3000); 
    </script>
    </body>
    </html>

     

     

    WEB-INF/view/serialdbtableview.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
        
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <div>  
      <table border="1">
          <tr>
            <th>번호</th>
          </tr>
    
        <c:forEach var="item" items="${list}">
          <tr>
            <td>${item.idx}</td>
          </tr>
         </c:forEach>
         
      </table>
    </div>
    <script>
       setInterval(function(){ location.href="/serialdbtableview" }, 3000); 
    </script>  
    </body>
    </html>

     

     

     

    ArduinoToSerial 프로젝트에서 Main.java를 실행시키자.

    그리고 서버를 실행시킨다. 웹 페이지를 2개 띄우자.

    각 웹 페이지의 주소창에 http://localhost:9090/serialdbview 과

    http://localhost:9090/serialdbtableview 를 입력해서 접속해보자.

    아래는 두 웹 페이지의 내용이다. 에러없이 잘 작동한다.

     

     

    아래는 현재까지 진행한 프로젝트 파일

    ArduinoToSerial.zip
    0.17MB
    springmvc2.zip
    2.53MB

    댓글

Designed by Tistory.