LJ

자바 웹 다루기 - 1. 클라이언트와 서버 간의 동작 본문

IT/자바 웹

자바 웹 다루기 - 1. 클라이언트와 서버 간의 동작

짱준재 2022. 10. 6. 14:43

* 웹 브라우저 

 

HTML 문서와 그림, 멀티미디어 파일등 월드 와이드 웹을 기반으로 한 인터넷의 컨텐츠를 검색 및 열람하기 위한 응용 프로그램의 총칭.

 

 

* JSP 

자바 서버 페이지(영어: JavaServer Pages[1], JSP)는 HTML내에 자바 코드를 삽입하여 웹 서버에서 동적으로 웹 페이지를 생성하여 웹 브라우저에 돌려주는 서버 사이드 스크립트 언어이다. Java EE 스펙 중 일부로 웹 애플리케이션 서버에서 동작한다.

자바 서버 페이지는 실행시에는 자바 서블릿으로 변환된 후 실행되므로 서블릿과 거의 유사하다고 볼 수 있다. 하지만, 서블릿과는 달리 HTML 표준에 따라 작성되므로 웹 디자인하기에 편리하다. 1999년 썬 마이크로시스템즈에 의해 배포되었으며 이와 비슷한 구조로 PHP, ASP, ASP.NET 등이 있다.

아파치 스트럿츠 자카르타 프로젝트 JSTL 등의 JSP 태그 라이브러리를 사용하는 경우에는 자바 코딩없이 태그만으로 간략히 기술이 가능하므로 생산성을 높일 수 있다.

 

프로그램의 발전 과정


클라이언트 pc 기반 프로그램 -> 클라이언트, 서버 기반 프로그램 -> 웹 기반 프로그램 

 

 

 

클라이언트 pc 기반 프로그램

 

자바로 일반 클라이언트가 PC에서 클라이언트가 직접 설치해서 사용하는 환율 계산기를 구현한 프로그램입니다.

이 구조의 문제는 기능이 추가 될 때마다 사용자 PC마다 업데이트하거나 새로 설치해야 한다는 것입니다.

 

다음은 pc에 설치되어 있는 환율 계산기 프로그램 코드입니다.

package ex01;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;


public class Calculator extends JFrame {
	private static float USD_RATE= 1124.70F;
	private static float JPY_RATE = 10.113F;
	private static float CNY_RATE = 163.30F;
	private static float GBP_RATE = 1444.35F;
	private static float EUR_RATE = 1295.97F;
			
	JLabel title = new JLabel("달러");
	JTextField operand1 = new JTextField(10);
	String[] opExpression = {"선택","달러", "엔화", "위안","파운드","유로"};
	JComboBox<String> opSelection = new JComboBox<String>(opExpression);
	JTextField txtResult = new JTextField(10);
	JButton btnClear = new JButton("다시입력");
	
	public Calculator() {
		Container contentPane = this.getContentPane();
		contentPane.setLayout(new FlowLayout());
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.pack();
		this.setVisible(true);
	}
	
	private void startFrame(){
		opSelection.addActionListener(new SelectionHandler());
		btnClear.addActionListener(new SelectionHandler());
		this.setTitle("환율 계산하기");
		this.add(title);
		this.add(operand1);
		this.add(opSelection);
		this.add(txtResult);
		this.add(btnClear);
		this.setSize(700,200);
		
	}
	
	class SelectionHandler implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			if(e.getSource()==opSelection){
				calculate();
			}else if(e.getSource()==btnClear){
				init();
			}
			
		}
	}

	private void calculate(){
		float won=Float.parseFloat(operand1.getText());
		String result=null;
		String operator=opSelection.getSelectedItem().toString();
		if(operator.equals("달러")){
			result=String.format("%.6f",won/USD_RATE);
		}else if(operator.equals("엔화")){
			result=String.format("%.6f",won/JPY_RATE);
		}else if(operator.equals("위안")){
			result=String.format("%.6f",won/CNY_RATE);
		}else if(operator.equals("파운드")) {
			result=String.format("%.6f",won/GBP_RATE);
		}else if(operator.equals("유로")) {
			result=String.format("%.6f",won/EUR_RATE);
		}
		txtResult.setText(result);
	}
	
	private void init(){
		operand1.setText("");
		txtResult.setText("");
	}
	public static void main(String[] args){
		Calculator calc=new Calculator();
		calc.startFrame();
		
	}

}

 

 

 

 

 

클라이언트, 서버 기반 프로그램

 

 

이 구조는 기존 클라이언트가 수행하는 모든 기능을 서버에서 수행합니다.

클라이언트의 기능은 줄고 클라이언트는 처리할 데이터가 있으면 네트워크를 통해 서버에 전달하고, 서버가 처리한 결과를 네트워크를 통해 다시 받아 결과를 출력하는 역할만 합니다.

 

서버 코드 입니다.

package ex02;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class RateServer {
	private static float USD_RATE= 1124.70F;
	private static float JPY_RATE = 10.113F;
	private static float CNY_RATE = 163.30F;
	private static float GBP_RATE = 1444.35F;
	private static float EUR_RATE = 1295.97F;
	
	public static void main(String[] args){
		InputStream is;
		BufferedReader br;
		BufferedWriter bw;
		PrintWriter pw=null;
		OutputStream os;
		ServerSocket serverSocket;
		Socket s1=null;
		String ipAddrs=null;
		String inMessage=null;
		float outMessage=0f;
		try{
			serverSocket= new ServerSocket(5434);
			System.out.println("서버 실행 중...");
			
			while(true){
				//클라이언트의 접속을 인지 시에 accept()메소드를 호출해서 소켓 객체를 생성한다.
				s1= serverSocket.accept();
				is=s1.getInputStream();
				os = s1.getOutputStream();
				br=new BufferedReader(new InputStreamReader(is));
				String data=br.readLine();
				System.out.println("서버 수신 데이터:"+data);
				String result=calculate(data);
				System.out.println(result);
				
				
				bw = new BufferedWriter(new OutputStreamWriter(os));
				pw=new PrintWriter(bw,true);
				pw.println(result);
				pw.close();
			}
		}catch(IOException ie){
			ie.printStackTrace();
		}
	}
	
	private static  String calculate(String data){
		String []token=data.split(",");
		
		float won=Float.parseFloat(token[0]);
		String operator=token[1];
		String result=null;
		if(operator.equals("달러")){
			result=String.format("%.6f",won/USD_RATE);
		}else if(operator.equals("엔화")){
			result=String.format("%.6f",won/JPY_RATE);
		}else if(operator.equals("위안")){
			result=String.format("%.6f",won/CNY_RATE);
		}else if(operator.equals("파운드")) {
			result=String.format("%.6f",won/GBP_RATE);
		}else if(operator.equals("유로")) {
			result=String.format("%.6f",won/EUR_RATE);
		}
		
		return result;
		
	}	
}

 

 

 

클라이언트 코드입니다.

 

package ex02;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;


public class RateClient extends JFrame{
	JLabel title = new JLabel("원화");
	JTextField operand1 = new JTextField(10);
	String[] opExpression = {"선택","달러", "엔화", "위안","파운드","유로"};
	JComboBox<String> opSelection = new JComboBox<String>(opExpression);
	JTextField txtResult = new JTextField(10);
	JButton btnClear = new JButton("다시입력");
	
	public RateClient() {
		Container contentPane = this.getContentPane();
		contentPane.setLayout(new FlowLayout());
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.pack();
		this.setVisible(true);
	}

	private void startFrame(){
		opSelection.addActionListener(new SelectionHandler());
		btnClear.addActionListener(new SelectionHandler());
		this.setTitle("클라이언트 프로그램");
		this.add(operand1);
		this.add(opSelection);
		this.add(txtResult);
		this.add(btnClear);
		this.setSize(700,200);
		
	}
	
	class SelectionHandler implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			if(e.getSource()==opSelection){
				calculate();
			}else if(e.getSource()==btnClear){
			  init();
			}
			
		}
	}
	
	private void init(){
		operand1.setText("");
		txtResult.setText("");
	}
	private void calculate(){
		float won=Integer.parseInt(operand1.getText());
		String result=null;
		String operator=opSelection.getSelectedItem().toString();
		
		 InputStream is;
		 BufferedReader br;
		 BufferedWriter bw;
		 OutputStream os;
		 PrintWriter pw=null;
		 
		try{
			Socket s1=new Socket("127.0.0.1",5434);
			os = s1.getOutputStream();
			is=s1.getInputStream();
			System.out.println("전송데이터:"+won+","+operator);
			
			
			bw = new BufferedWriter(new OutputStreamWriter(os));
			pw=new PrintWriter(bw,true);
		    pw.println(won+","+operator);
		    
		    br=new BufferedReader(new InputStreamReader(is));
			result=br.readLine();
			System.out.println("클라이언트 수신 데이터:"+result);
			txtResult.setText(result);
			s1.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		RateClient calc=new RateClient();
		calc.startFrame();
		
	}	
}

 클라이언트, 서버 기반 프로그램은 기능이 변경되어도 모두 서버에서 처리하면 되기 떄문에 클라이언트 프로그램을 수정할 필요가 없습니다. 중요한 기능은 서버에서 처리하므로 클라이언트 PC 기반 프로그램보다 보안 측면에서도 훨씬 우수합니다.

하지만 단순히 기능만 추가되는 경우가 아니라면 클라이언트의 프로그램도 수정해야 하기 떄문에 이 역시 추가 작업이 필요합니다.

 

 

웹 기반 프로그램

 

웹 기반 프로그램의 경우 클라이언트는 자신이 사용하는 클라이언트 프로그램을 직접 설치하는 것이 아니라 사용자 컴퓨터의 웹 브라우저를 통해 해당되는 HTML 문서를 서버에 요청합니다. 그러면 서버에서는 요청받는 HTML 문서를 브라우저에 전송하여 해당 기능을 담당하는 화면을 보여줍니다.

즉, 웹 기반 프로그램의 경우 사용자가 사용하는 프로그램의 기능이나 화면이 바뀌면 서버에서 모두 처리합니다. 클라이언트-서버 기반 프로그램과 마찬가지로 클라이언트가 특별히 수행해야 할 작업이 없습니다.

모든 기능을 서버에서 처리하므로 보안 면에서도 월등히 우수합니다.

 

package ex01;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RateServlet
 */
@WebServlet("/calc")
public class RateServlet extends HttpServlet {
	private static float USD_RATE= 1124.70F;
	private static float JPY_RATE = 10.113F;
	private static float CNY_RATE = 163.30F;
	private static float GBP_RATE = 1444.35F;
	private static float EUR_RATE = 1295.97F;
	

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request,response);
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request,response);
	}
	
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			request.setCharacterEncoding("utf-8");
			response.setContentType("text/html; charset=utf-8");
			PrintWriter pw = response.getWriter();
			String command=request.getParameter("command");
			String won=request.getParameter("won");
			String operator=request.getParameter("operator");
			
			if(command!= null && command.equals("calculate")){
				String result = calculate(Float.parseFloat(won),operator);
				pw.print("<html><font size=10>변환결과</font><br>");
				pw.print("<html><font size=10>"+result+"</font><br><br><br>");
				pw.print("<a href='/rateServer/calc'>환율 계산기 </a>");
				return;
			}
			
			pw.print("<html><title>환율계산기</title>");
			pw.print("<font size=5>환율 계산기</font><br>");
			pw.print("<form  name='frmCalc' method='post'  action='/rateServer/calc'  />  ");
			pw.print("원화: <input type='text' name='won' size=10  />  ");
			pw.print("<select name='operator' >");
			pw.print("<option value='dollar'>달러</option>");
			pw.print("<option value='en'>엔화</option>");
			pw.print("<option value='wian'>위안</option>");
			pw.print("<option value='pound'>파운드</option>");
			pw.print("<option value='euro'>유로</option>");
			pw.print("</select>");
			pw.print("<input type='hidden' name='command' value='calculate'  />  ");
			pw.println("<input type='submit' value='변환'  />");
			pw.println("</form>");
			pw.print("</html>");
			pw.close();
	}

	
	private static  String calculate(float won ,String operator){
		String result=null;
		if(operator.equals("dollar")){
			result=String.format("%.6f",won/USD_RATE);
		}else if(operator.equals("en")){
			result=String.format("%.6f",won/JPY_RATE);
		}else if(operator.equals("wian")){
			result=String.format("%.6f",won/CNY_RATE);
		}else if(operator.equals("pound")) {
			result=String.format("%.6f",won/GBP_RATE);
		}else if(operator.equals("euro")) {
			result=String.format("%.6f",won/EUR_RATE);
		}
		return result;
	}
}

 

참고문헌: 위키백과, 자바 웹을 다루는 기술(책)

'IT > 자바 웹' 카테고리의 다른 글

MVC 란?  (0) 2022.11.08
Spring 종류  (0) 2022.11.08
자바 웹 다루기 - 2. 웹 프로그래밍과 JSP  (0) 2022.10.06
Comments