전체 글

Spring 에서 깃허브 프로젝트 가져오기


Import - Git - Projects From Git - Clone URI 하고 깃허브의 주소와 아이디 비밀번호 입력한다



Github에 Commit할때

마우스 우클릭 - Team - Commit

저장소에 저장되지 않은 변경된 내역 중에 커밋할 내용을 드래그한 후

커밋메세지를 작성한 후 커밋한다.

커밋과 동시에 PUSH해서 깃허브에 올리고 싶다면 Commit and Push를 클릭한다

Push할때 브랜치를 생성할 수 있다.





88DAY / MySQL 랭크함수

2017. 8. 8. 09:00

Oracle과 달리 MySQL에서는 랭크함수가 없어서 구현해줘야한다.


같은 점수면 동점처리하고

원래는 1등 1명, 2등 2명이면, 다음 등수는 4등이 되어야하지만

우리 프로젝트에서 처리하기엔 더 불편할 것같아서 다음 등수는 3등이 되게하였다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    SELECT 
        sns_board_no, 
        CASE
        WHEN @prev = liker then @Rank 
        WHEN @prev := liker then @Rank := @Rank +1 
        END AS rank, 
        liker
    FROM 
        (
        SELECT sns_board_no ,count(sns_like_no) as liker
        FROM sns_like
        WHERE MONTH(sns_like_date) = (MONTH(NOW())-1)
        GROUP BY sns_board_no 
        ORDER BY count(sns_like_no) DESC
        )sub1
    CROSS JOIN (select @Rank := 0 ,@prev :=  NULL) sub2
    ;
cs



MySQL 사용자 변수 사용


1)SET을 사용하여 변수설정


1
SET @exam = 1;
cs

2)@var := expr

1
SELECT @exam := 1;
cs




카페24 호스팅 신청


카페24에 회원가입한 후 서비스를 신청한다.



톰캣 JSP 광호스팅의 제일 저렴한 절약형으로 결정.


가입 후 처음으로 호스팅을 신청하여 신청하지 않은 아이디라고 뜨는데

2번째 이상 호스팅 신청시에는 새로운 아이디가 발급된다.

최초로 신청한 아이디인 부아이디에서 2번째 신청시 발급된 자아이디를 관리할 수 있다.


신청할 때 MySQL에서 사용할 비밀번호를 설정해준다.



서버환경 / 기간 / 도메인 선택하고 결제하면 신청완료.

기간이 길면 할인율이 높아진다.

신규도메인 등록하려면 돈 내야해서 무료도메인 쓰는데 카페24가입 아이디가 도메인된다.




신청할 때는 몰랐는데

닷홈의 무료호스팅 신청을 이용하면 무료로 도메인을 설정할 수 있다.

닷홈에서는 개인 당 3개의 계정을 무료호스팅 받을 수 있다


http://www.dothome.co.kr/web/free/index.php


닷홈으로 도메인을 신청하였으면 보유도메인에 체크하여 주소를 입력해준다.

그 후 닷홈으로 가서 네임서버에 카페24등록한다.

다음에 기회가 되면 해봐야겠다.

추가)닷홈 무료도메인은 지원하는 버전이 너무낮아서 활용도가 낮다한다.

Spring 개발단계 - 준비


(1)Spring Tool 설치


Spring Community http://spring.io/


>TOOLS 들어가서 다운로드


(2)톰캣 서버 가져오기


-기존 서버아닌 톰캣 9.0사용하였다.


(3) legacy project생성 

-MVC프로젝트선택



(4)JRE System Library 버전 변경


[ Java build path ]에서 JRE System Library 을 수정한다.




(5)web.xml파일 수정과 root-context.xml파일삭제를 한다.


-servlet 3.0 으로 변경

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>
 
cs


-해당부분삭제

]


: 부팅이 두개 되기때문에 



(6)

pom.xml 파일에서 springframework 버전을 최신버전(4.3.9.RELEASE)으로 다운로드 한다.

mysql도 추가한다.


1
2
3
4
5
6
7
<!-- mysql -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>
cs

(7)servlet-context.xml 파일수정


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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.xsd">
 
    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
    
    <!-- Enables the Spring MVC @Controller programming model -->
    <mvc:annotation-driven />
 
    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <mvc:resources mapping="/resources/**" location="/resources/" />
 
    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <context:component-scan base-package="com.jjdev.mvc" />
 
</beans>
 
cs


(8)마우스 우클릭 - [ run as ] - [ run on server] 실행확인





(9)Board , BoardDao 클래스 생성


(10)boardAdd.jsp 생성


(11)BoardController 클래스 생성후 BoardAdd()메소드 추가


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.jjdev.mvc;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class BoardController {
    @Autowired
    BoardDao boardDao;
    @RequestMapping(value="/boardAdd", method=RequestMethod.GET)
    public String boardAdd(){
        return "boardAdd";
    }
    @RequestMapping(value="/boardAdd", method=RequestMethod.POST)
    public String boardAdd(Board board){
        boardDao.insertBoard(board);
        return "redirect:/";
    }
    
    
}
 
cs


(12)Run on Server 후 주소창에 boardAdd 입력





(13)글작성 후 mysql에 데이터저장되었는지 확인.

61DAY / jQuery 메서드

2017. 6. 30. 09:16

선택기 메서드

children : 선택된 대상의 1단계 자식검색

find : 선택된 대상의 자식 전체 검색

parent : 선택된 대상의 1단계 부모검색

parents : 선택된 대상의 html최상위까지 검색(매개변수로 인하여 브레이크 가능) 최상위:html

first : 선택된 대상의 첫번째를 선택

last : 선택된 대상의 마지막을 선택

eq : 선택된 대상의 해당 index를 선택

index : 선택된 대상의 index값을 구한다. ex) $('선택자').index($(this));


html제어메서드

wrap : 선택된 대상에 부모를 생성한다

append : 선택된 대상의 자식요소 마지막에 html을 생성한다.

prepend : 선택된 대상의 자식요소 첫번째에 html을 생성한다.

html : 선택된 대상의 내부의 html을 생성한다.

next : 선택된 대상의 다음순서에 html을 삽입한다.

prev : 선택된 대상의 이전순서에 html을 삽입한다.


비교메서드

prop  : 선택대상의 속성의 상태를 비교하여 boolean으로 리턴해준다. 혹은 실행

ex) 상태정보 - var isCheck = $('선택자').prop('checked');

상태실행 : $('선택자').prop('checked', true or false);

 $('선택자').prop('readonly', true);-- true일때 readonly

is : 선택대상의 속성 및 존재여부를 확인하여 boolean으로 리턴해준다.

ex) 상태정보 : var isCheck =$('선택자').prop(':checked');

상태정보 : var isCheck = $('선택자').prop('클래스 혹은 아이디');





$('article').parent().find('h1:eq(0)').remove();

article의 부모의 1단계아래자식중 h1의 첫번째


var btn1 =$('<button></button>');

btn1.attr('type','button');

btn1.addClass('add');

btn1.text('추가');


var btn2 =$('<button></button>');

btn2.attr('type','button');

btn2.addClass('del');

btn2.text('삭제');


$(document).on('click','.add',function(){

var clone = $(this).parents('article').clone();

clone.find('h1').text('냠냠');

$('article').parent().prepend(clone);

});----만든객체도 추가됨


$('.add').click(function(){

var clone =$(this).parents('article').clone();

clone.find('h1').text('한국스마트정보교육원');

$('article').parent().prepend(clone);

}); ===얜 안됨



$(document).on('click','.indexCheck',function(){

var parentObj = $(this).parents('article');

var ptext = parentObj.find('p').text();

alert(ptext);

});



공공api를 이용한 미세먼지 확인 앱 만들기


(1)공공api를 얻기위해  권한을 신청한다. 저번에 신청한 api를 사용하겠다

https://www.data.go.kr/


(2)새 프로젝트를 생성한다. 버전은 android4.4(kikat)으로 생성하였다


(3)AndroidManifest.xml파일에 permission을 추가한다

<uses-permission android:name="android.permission.INTERNET"></uses-permission>



(4)Air라는 자바파일안에


DataTime, 시도명을 Setter and Getter , To String 해준다.


(5)AirService.java 생성


package com.example.airapp.airapp;

import android.util.Log;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;


public class Airservice {
public static Air getAir() {
//새로운 객체를 불러온다.
Air air = new Air();

String str = getAirList();

try {
//XML파싱
//(1)factory 생성한다.
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//(2)factory에서 pullparser를 생성한다.
XmlPullParser parse = factory.newPullParser();
//(3)parser에서 사용할 데이터를 입력한다. StringReader타입으로 데이터를 전달해줘야 하기 때문에 getAirList라는 메서드를 생성하였다.
parse.setInput(new StringReader(str));
//(4)현재 팟의 이벤트 타입을 받는다.
int type = parse.getEventType();

boolean flag = false; //값이 참일때만 수행하기위해 생성
String local = "";
//(5)LOOP구문 : parser의 마지막 </tag>가 될때까지
while(type != XmlPullParser.END_DOCUMENT){
//(6)<tag>text</tag>이므로 startTag뒤에있는 Text를 찾기위한 switch절이다.
switch(type){

case XmlPullParser.START_TAG: //(6)-1.start Tag가 다음 중 하나일 때 flag값이 true가 된다.
local = parse.getName();
if(local.equals("dataTime")
||local.equals("seoul")
|| local.equals("busan")
|| local.equals("daegu")
|| local.equals("incheon")
|| local.equals("gwangju")
|| local.equals("daejeon")
|| local.equals("ulsan")
|| local.equals("gyeonggi")
|| local.equals("gangwon")
|| local.equals("chungbuk")
|| local.equals("chungnam")
|| local.equals("jeonbuk")
|| local.equals("jeonnam")
|| local.equals("gyeongbuk")
|| local.equals("gyeongnam")
|| local.equals("jeju")
|| local.equals("sejong")){
flag = true;
}
break;
case XmlPullParser.TEXT: //(6)-2.위의 case조건에 맞았다면 flag값은 true이므로 if문이 실행된다.
if(flag) {
if(local.equals("dataTime")) { //(6)-3.조건에 맞는 TEXT값을 int형으로 바꾸어 세팅한다. flag값은 false가된다
air.setDataTime(parse.getText());
}else if(local.equals("seoul")) {
air.setSeoul(Integer.parseInt(parse.getText()));
} else if(local.equals("busan")){
air.setBusan(Integer.parseInt(parse.getText()));
} else if(local.equals("daegu")){
air.setDaegu(Integer.parseInt(parse.getText()));
} else if(local.equals("incheon")){
air.setIncheon(Integer.parseInt(parse.getText()));
} else if(local.equals("gwangju")){
air.setGwangju(Integer.parseInt(parse.getText()));
} else if(local.equals("daejeon")){
air.setDaejeon(Integer.parseInt(parse.getText()));
} else if(local.equals("ulsan")){
air.setUlsan(Integer.parseInt(parse.getText()));
} else if(local.equals("gyeonggi")){
air.setGyeonggi(Integer.parseInt(parse.getText()));
} else if(local.equals("gangwon")){
air.setGangwon(Integer.parseInt(parse.getText()));
} else if(local.equals("chungbuk")){
air.setChungbuk(Integer.parseInt(parse.getText()));
} else if(local.equals("chungnam")){
air.setChungnam(Integer.parseInt(parse.getText()));
} else if(local.equals("jeonbuk")){
air.setJeonbuk(Integer.parseInt(parse.getText()));
} else if(local.equals("jeonnam")){
air.setJeonnam(Integer.parseInt(parse.getText()));
} else if(local.equals("gyeongbuk")){
air.setGyeongbuk(Integer.parseInt(parse.getText()));
} else if(local.equals("gyeongnam")){
air.setGyeongnam(Integer.parseInt(parse.getText()));
} else if(local.equals("jeju")){
air.setJeju(Integer.parseInt(parse.getText()));
} else if(local.equals("sejong")){
air.setSejong(Integer.parseInt(parse.getText()));
}
flag = false;
}
break;
default:
break;
}
//(7)parser의 진행을 다음(태그,속성,글자...)로 이동한다.
type = parse.next();
}

} catch (Exception e) {
e.printStackTrace();
}

return air;
}

private static String getAirList() {
HttpURLConnection conn = null;
BufferedReader rd = null;
StringBuilder sb = null;
try {
Log.v("air","try...");
StringBuilder urlBuilder = new StringBuilder("http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnMesureLIst"); /*URL*/
urlBuilder.append("?" + URLEncoder.encode("ServiceKey", "UTF-8") + "=서비스키"); /*Service Key*/
urlBuilder.append("&" + URLEncoder.encode("itemCode", "UTF-8") + "=" + URLEncoder.encode("PM10", "UTF-8")); //미세먼지 정보만 불러옴
urlBuilder.append("&" + URLEncoder.encode("dataGubun", "UTF-8") + "=" + URLEncoder.encode("HOUR", "UTF-8")); //시간별 데이터
urlBuilder.append("&" + URLEncoder.encode("pageNo", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8")); //데이터페이지중 1번페이지
urlBuilder.append("&" + URLEncoder.encode("numOfRows", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8")); //최신데이터 1개를 가지고온다.

URL url = new URL(urlBuilder.toString());
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
Log.v("air","Response code: " + conn.getResponseCode());
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
Log.v("air","if...");
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
//예외처리
} catch (IOException e) {
Log.v("air","catch...");
e.printStackTrace();
} finally {
Log.v("air","finally...");
try {
rd.close();
} catch (IOException e) {
e.printStackTrace();
}
conn.disconnect();
}
return sb.toString();
}
}



(6)MainActivity

public class MainActivity extends AppCompatActivity {
TextView dataTime;
ProgressBar seoulbar;
ProgressBar busanbar;


@Override
protected void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

dataTime = (TextView)findViewById(R.id.dataTime);
seoulbar = (ProgressBar)findViewById(R.id.seoulbar);
busanbar = (ProgressBar)findViewById(R.id.busanbar);


new MyThread().execute();

}

class MyThread extends AsyncTask{
@Override
protected Object doInBackground(Object[] params){
Air air = Airservice.getAir();
Log.d("air",air.toString());
return air;
}
//주체 : mainThread
@Override
protected void onPostExecute(Object o){
Log.d("air","onPostExecute:"+o.toString());
Air air = (Air)o;
dataTime.setText(air.getDataTime());
seoulbar.setProgress(air.getSeoul());
busanbar.setProgress(air.getBusan());


}


}
}



(7)activity_main.xml





버튼 클릭 이벤트 처리


1) 액티비티에서 View타입을 매개변수로받는 메서드 생성 후

   레이아웃에서 메서드 호출설정


레이아웃


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.firstapp.firstapp.MainActivity">

<Button
android:id="@+id/hellobtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click"

android:onClick="testOnClick"/>

</android.support.constraint.ConstraintLayout>



액티비티


public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.activity_main);

}

public void testonClick(View view) {
Toast.makeText(MainActivity.this, "EventTest Click", Toast.LENGTH_SHORT).show();
}
}
}

2)이벤트리스너를 사용


공통레이아웃

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.firstapp.firstapp.MainActivity">

<Button
android:id="@+id/hellobtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click"
</android.support.constraint.ConstraintLayout>


public class MainActivity extends AppCompatActivity  {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.activity_main);

Button button = (Button)findViewById(id.hellobtn);
button.setOnClickListener(new MyListener());
}
class MyListener implements View.OnClickListener {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "EventTest Click", Toast.LENGTH_SHORT).show();
}
}
}



3)익명클래스를 사용


public class MainActivity extends AppCompatActivity  {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.activity_main);

Button button = (Button)findViewById(id.hellobtn);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "EventTest Click", Toast.LENGTH_LONG).show();

}
});
}
}


4)액티비티 스스로 이벤트리스너 구현



public class MainActivity extends AppCompatActivity implements View.OnClickListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.activity_main);

Button button = (Button)findViewById(id.hellobtn);
button.setOnClickListener(this);

}
@Override
public void onClick(View v) {
Toast.makeText(this, "EventTest Click", Toast.LENGTH_LONG).show();

}
}



터치 이벤트 처리

(1)새 프로젝트를 생성한다

(2) TextView 위젯을 생성하고 
    높이와 넓이를 match_parent 타입으로 설정하여 화면 전체를 덮는다



(3) 액티비티


화면에서 터치가 끝날 때 x좌표값을 받아서 처음 터치시좌표와 비교후 
증가인지 감소인지(우측으로 이동했냐 좌측으로 이동했냐)에 따라 분기시킨다.
-10 , +10 으로 값을 설정한 이유는 너무 작은 값에는 반응하지 않도록 하기위해서이다.

 
true를 리턴하면 이벤트를 소멸시키면서 다음이벤트로 진행되지 않는다.


안드로이드는 문자열을 다룰때 자바의 String타입이 아닌 CharSequence라는 자체 문자열 타입을 사용한다. 

그래서 안드로이에서 생성된 문자열에 자바API를 사용할려면 먼저 toString()메서드를 이용하여 CharSequence타입을 String타입으로 변경해야 한다.



안드로이드  프레임워크

C기반 개발툴

안드로이드 스튜디오 Android Studio 시작하기

안드로이드 스튜디오 다운로드

https://developer.android.com/studio/index.html




API7.0 


1) 환경변수 설정하기


 

안드로이드 스튜디오를 사용하기 전에 Java JDK 환경변수를 설정해준다. 

[제어판] - [시스템] - [시스템보호] - [고급]탭에 환경변수를 클릭한 후

아래 시스템변수 새로만들기에

변수 이름 : JAVA_HOME

변수값  : JDK설치된 경로

를 입력해준다



(2)새 프로젝트만들기




안드로이드 스튜디오 설치가 끝나면 실행하여 새로운 프로젝트를 생성한다.

프로젝트 명과 도메인 명 저장될 경로를 지정한다.




기본적으로 생성되는 액티비티와 레이아웃


(2)가상머신 설정하기



프로젝트에서 API 7 버전인 Nougat를 사용할 것이기 때문에 다운로드해준다.



디바이스 추가 완료!



휴대폰에 연결하기


(1)기종에 맞는 USB 드라이브 소프트웨어 설치후


(2)[ Tools ] - [ Android ] - [ Android Device Mointor ] 


##안드로이드 스튜디오 디바이스 연결이 되지 않을 때


https://freeandroidroot.com/download-and-install-universal-adb-driver/


ADB드라이버를 설치 후 다시 시도한다.


아이콘 바꾸기

(1)아이콘을 다운로드 받는다

무료아이콘 지원하는 사이트

(2) mipmap 폴더안에 png파일을 붙여넣는다


(3) AndroidMainfest.xml 파일에서 다음과 같이 수정한다.


android:icon="@mipmap/png파일명"

파일명은 영소문자만 가능하다



45DAY / JSP지시어

2017. 6. 8. 09:17

JSP지시어 (Directive)

 

<%@ page langauge = "java" %>

JSP파일 내에서 사용 될 스크립트 언어 지정


<%@ page extends = "클래스명" %>

상속할 부모 클래스 지정


<%@ page import = "패키지명.클래스명" %>

Java의 import와 같은기능


<%@ page session = "true" %>

JSP내에서 세션사용

*세션(Session) : HTTP의 Stateless특성으로 인해 커넥션을 매번 새로 생성해야하기 때문에 동일한 클라이언트에 대해 정보를 유지할 필요가 있는 경우, 정보유지가 가능하도록 만드는 가상의 커넥션


<%@ page buffer = "8kb" %>

JSP페이지가 서블릿으로 변환되어 응답을 생성해 클라이언트에 전송할 때 사용되는 버퍼의 크기 지정

none으로 설정 할 경우 버퍼를 사용하지 않는다


<%@ page autoFlush = "true" %>

buffer속성에서 지정한 버퍼가 다 채워졌을경우

true : 클라이언트에게 전송 후 버퍼비운다

false : Exception발생시킨다


<%@ page isThreadSafe = "true" %>

다중스레드에 의한 동시접근을 차단한다


<%@ page info = "페이지설명%>

페이지전체에 대한 주석의 역할


<%@ page errorPage = "errorpage.jsp" %>

예외가 발생했을 때 에러페이지를 지정해 에러페이지에서 예외처리함


<%@ page contentType = "text/html" %>

JSP페이지가 전송할 응답의 MINE형식 지정 대분류/소분류 순으로 명시한다


<%@ page isErrorPage = "false" %>

현재 페이지가 다른 페이지에서 발생한 예외처리할 페이지 일때 지정한다


<%@ page pageEncoding = "euc-kr" %>

JSP페이지 문자셋 인코딩방식을 지정

 



액션태그


파일 업로드

<form method="post" enctype="multipart/form-data">

</form>


enctype 속성을 multipart/form-data  지정하지 않으면 파일객체가 아닌 파일이름 이 문자열형태로 전송된다.



예제 / 단일 파일 업로드 


<form action="./partUplaodPro1" method="post" enctype="multipart/form-data">

<label for ="writer">작성자</label>

<input type=text name="writer" id="writer"><br>

<label for ="partFile1">업로드 파일</label>

<input type="file" name="partFile1" id="partFile1">

<input type="submit" value="업로드">



 

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import java.util.UUID;

 

import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.annotation.MultipartConfig;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.Part;

 

 

@WebServlet("/partUplaodPro1")

@MultipartConfig(

            fileSizeThreshold=0 ,

            location = "d:/upload"

            )

public class partUploadPro1 extends HttpServlet {

     

      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

           

            request.setCharacterEncoding("utf-8");

            String writer = request.getParameter("writer");

            System.out.println(writer);

            Part part = request.getPart("partFile1");

            String contentDisposition = part.getHeader("content-disposition");

           

            String contentType = part.getHeader("content-type");

            System.out.println(part);

           

            if(contentType.equals("image/gif")

                  || contentType.equals("image/jpeg")

                  || contentType.equals("image/png")){

                 

           

            System.out.println(contentDisposition);

            int dotPosition = contentDisposition.lastIndexOf(".");

            String temp = contentDisposition.substring(dotPosition,contentDisposition.length()-1);

            UUID uuid = UUID.randomUUID();

            String fileName = uuid.toString()+temp;

            part.write(fileName);

            File srcFile = new File("d:\\upload\\"+fileName);

            File destFile = new File("d:\\upload\\_"+fileName);

          

            BufferedImage srcbi = ImageIO.read(srcFile);

            BufferedImage destbi = new BufferedImage(50, 50, BufferedImage.TYPE_3BYTE_BGR);

            Graphics2D g = destbi.createGraphics();

            g.drawImage(srcbi, 0, 0, 50, 50, null);

            ImageIO.write(destbi, temp.substring(1), destFile);

           

            }

            else{

                  response.sendRedirect("./partUploadForm1.jsp");

            }

                  

      }

 

 

}

 

코드설명 /

@MultipartConfig 는 서블릿에서  multipart/form-data 형태로 전송된 데이터를 처리할 수 있게 지정한다.

파일이 최종 저장될 경로는 d:/upload 이고

업로드된 파일이 0바이트보다 커지면 임시 디렉토리에 저장된다.


파일이 gif,jpeg,png형식이 아닐경우 partUploadForm1.jsp로 돌아가고 맞을경우엔 흰화면


+ Recent posts