public String doE(RedirectAttributes rttr){
//logger.info("리다이렉트.....................");
rttr.addFlashAttribute("msg", "이미 등록된 사용자 입니다.");
return "redirect:/error";
}
1 표현언어의 표현방식
$(expr}
2. 표현언어의 기본객체
pageScope :: page 범위에 포함된 속성 값에 접근
라이브러리 | 하위기능 | 접두어 | 관련 URL |
코어 | 변수지원 , 흐름제어 , URL처리 | c | http://java.sun.com/jsp/jstl/core |
XML | XML 코어 , 흐름제어 , XML변환 | x | http://java.sun.com/jsp/jstl/xml |
국제화 | 지역 , 메시지 형식 , 숫자및 날짜형식 | fmt | http://java.sun.com/jsp/jstl/fmt |
데이터베이스 | SOL | sql | http://java.sun.com/jsp/jstl/sql |
함수 | 콜렉션처리 , String 처리 | fn | http://java.sun.com/jsp/jstl/functions |
기능분류 | 태그 | 설 명 |
변수지원 | set | JSP에서 사용될 변수 설정 |
remove | 설정한 변수 제거 | |
흐름제어 | if | 조건에 따라 내부코드수행 |
choose | 다중조건을처리 | |
forEach | 콜렉션이나 Map의 항목처리시사용 | |
forTokens | 구분자로 분리된 각각의 토근을 처리할때 사용 | |
URL 처리 | import | URL을 사용하여 다른자원의 결과삽입 |
redirect | 지정한 결로로 리다이렉트한다 | |
url | url재작성 | |
기타태그 | catch | 예외처리에 사용 |
out | JspWriter에 내용을 알맞게 처리후 출력 |
문자 | 변환된 형태 |
< | < |
> | > |
& | & |
' | ' |
'" | " |
fn:substringBefore , fn:substringAtter
파일 이름만 가져오고 싶었는데 lastIndexOf 를 써봐도 안됨.
jstl 함수에는 lastIndexOf가 없다
대신 fn:substringBefore , fn:substringAtter 존재
<c:set var="name" value="son01.gif />
${fn:substringBefore( name ,'.')}
<c:out value="${name}" />
결과 -> son01
<img src="${pageContext.request.contextPath}${ImgUrlPath}thumb/${fn:substringBefore(list.FILE_SAVE_NAME,'.')}<s:message code='board.thumb.backName' />.<s:message code='board.thumb.extension' />" alt="" />
fn:split
예) 02-123-4567 이란 값을 split 처리 할 경우 배열의 순서값으로 찾아서 처리 함.
${fn:split(list.TEL,'-')[1]} - ${fn:split(list.TEL,'-')[2]}
[출처] jstl 함수 정리2|작성자 237
[출처] jstl 함수 정리|작성자 237
OKJSP( http://www.okjsp.pe.kr/seq/72792 )
1. 모든 문서는 UTF-8 인코딩으로 저장되어야 합니다.
에디트 플러스의 경우 도구 -> 기본설정 -> 파일 부분에서 새 파일 형식을
UTF-8 로 해놓음으로써 새파일 작성시 UTF-8을 기본으로 작성할수 있고,
이미 다른 인코딩 타입에서 작성된 문서인 경우 내용을 모조리 Ctrl+C로 복사후
문서 -> 인코딩 변경 로드에서 UTF-8로 변경후 다시 붙여넣기 하면 됩니다.
이클립스의 경우 Package Explorer 에서 프로젝트에서 우측 버튼을 누른 후
Properties->Info->Text file encoding->Other 을 UTF-8 로 잡아주면 됩니다.
( 기존 다른 인코딩 타입에서 작성된 문서 내부 한글은 모조리 깨지게 됨 )
2. jsp 파일 상단에는 다음과 같은 방식으로 UTF-8 설정합니다.
<%@ page contentType = "text/html;charset=utf-8" %>
3. 서블릿은 다음과 같은 방식으로 UTF-8을 설정합니다.
request.setCharacterEncoding("utf-8")
4. 자바스크립트에서 encodeURIComponent 처리 및 톰캣 server.xml 의 설정 변경
위 1,2,3번의 방식으로 하면 post 방식의 데이터는 잘 받지만
get 방식의 데이터는 한글이 깨집니다.
이와 같은 경우 자바스크립트의 encodeURIComponent 함수와
server.xml 을 이용하여 처리하면 됩니다.
4.1 server.xml
톰캣 폴더의 conf 폴더에는 server.xml 파일이 존재합니다.
에디터로 열어보면
예)
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
값이 약간 틀릴수 있지만 초기 셋팅 값이 보통 저러하고,
Connector 은 초기에 2개가 있는데 8080 포트 부분을 수정하면 됩니다.
수정하는 방법은
URIEncoding="UTF-8" 을 추가하면 됩니다.
예)
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="utf-8" />
위와 같이 했다고 해결되는 것은 아닙니다. get 방식으로 데이터를 전송하면
자바 파일에서 확인 했을 경우 물음표 값만 넘어옵니다.
get 방식으로 보낼 경우 자바스크립트로 변환을 해줍니다.
예를 들어 "한글"을 자바스크립트에서
<SCRIPT>alert( encodeURIComponent("한글") )</SCRIPT>
처럼 encodeURIComponent 함수로 변환하게 되면 %ED%95%9C%EA%B8%80 으로
변환됩니다. 이 값을 주소에 "한글" 대신에 넣게 되면 자바에서 알아서 잘~ 받습니다 ^^
[출처] [본문스크랩] [스크랩][인코딩] UTF-8관련 개발|작성자 일리
utf-8 인코딩을 이용한 한글 url 처리 [ 조회수: 393 ] | ||||||||||||||||||||||||||
개요
구조
관련자료utf-8 체크
utf-8 인코딩 체크 예제
package util; import java.io.UnsupportedEncodingException; /** * <pre> * 작성자 : 이종희 (qola@naver.com) * JAlbum.com (http://jalbum.net/download.jsp?ref=list) 소스 참고함. * <b>특정 문자열이 utf-8 인코딩인지 아닌지 체크한다.</b> * * utf-8 인코딩 패턴인 110xxxxx 10xxxxxx , 1110xxxx 10xxxxxx 10xxxxxx 인지 비교한다. * 2바이트 (110xxxxx 10xxxxxx) 패턴의 유니 코드 중복으로 인해 100% 검증할수 없지만 * 한글의 경우 3byte 로 표기 되므로 2바이트 패턴일 경우 utf-8 인코딩이 아닌것으로 간주한다. * * 따라서 000080 ~0007FF 영역의 라틴 문자, 그리스 문자, 키릴 문자, 콥트 문자, * 아르메니아 문자, 히브리 문자, 아랍 문자 등은 utf-8 인코딩을 비교할수 없다. * * 수정된 utf-8의 의한 null값 \u0000 은 11000000 10000000 로 표기되지만 무시하기로 한다. * * </pre> */ public class UTFUtil { public static boolean isUTF8(String str) throws Exception{ byte[] bytes=str.getBytes("ISO-8859-1"); return isUTF8(bytes,0,bytes.length); } public static boolean isUTF8(byte[] buf, int offset, int length) { boolean yesItIs = false; for (int i=offset; i<offset+length; i++) { if ((buf[i] & 0xC0) == 0xC0) { // 11xxxxxx 패턴 인지 체크 int nBytes; for (nBytes=2; nBytes<8; nBytes++) { int mask = 1 << (7-nBytes); if ((buf[i] & mask) == 0) break; } //CJK영역이나 아스키 영역의 경우 110xxxxx 10xxxxxx 패턴으로 올수 없다. if(nBytes==2) return false; // Check that the following bytes begin with 0b10xxxxxx for (int j=1; j<nBytes; j++) { if (i+j >= length || (buf[i+j] & 0xC0) != 0x80) return false; } if(nBytes==3){ // 유니코드 형태로 역치환 해서 0x0800 ~ 0xFFFF 사이의 영역인지 체크한다. char c = (char) (((buf[i] & 0x0f) << 12) + ((buf[i+1] & 0x3F) << 6) + (buf[i+2] & 0x3F)); if(!(c >= 0x0800 && c <= 0xFFFF)){ return false; } } yesItIs = true; } } return yesItIs; } }
한글 URL 사용시 문제 발생 케이스
해결책
구현 예제
|
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ page import="java.util.Calendar"%>
<%@ page import="java.util.Date"%>
<%@ page import="java.text.DecimalFormat"%>
<%@ page import="java.text.SimpleDateFormat" %>
<%!
public static String getdate(int mountdate){
DecimalFormat df = new DecimalFormat("00");
Calendar calendar = Calendar.getInstance();
calendar.add(calendar.DATE, mountdate);
String year = Integer.toString(calendar.get(Calendar.YEAR));
String month = df.format(calendar.get(Calendar.MONTH) + 1);
String day = df.format(calendar.get(Calendar.DATE));
String date = year + "-" + month + "-" + day;
return date;
}
public static int fnDateDiff(String stDate,String etDate){
long d1,d2;
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
String[] arr1 = stDate.split("-");
String[] arr2 = etDate.split("-");
c1.set(Integer.parseInt(arr1[0]),Integer.parseInt(arr1[1]),Integer.parseInt(arr1[2]));
c2.set(Integer.parseInt(arr2[0]),Integer.parseInt(arr2[1]),Integer.parseInt(arr2[2]));
d1 = c1.getTime().getTime();
d2 = c2.getTime().getTime();
int days =(int)((d2-d1)/(1000*60*60*24));
return days;
}
%>
<%@ include file="socket.jsp" %>
<%
response.setHeader("Cache-Control","no-store");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
if (request.getProtocol().equals("HTTP/1.1")){
response.setHeader("Cache-Control", "no-cache");
}
String sig_req_id = request.getParameter("sig_req_id");
Cookie[] cookies=request.getCookies();
String userDomain = "";
if(cookies !=null && cookies.length > 0){
for(int i=0; i<cookies.length; i++){
if( cookies[i].getName().equals("UD") ){
userDomain = cookies[i].getValue();
}
}
}else{
userDomain = "localhost";
}
String [] result = GetIsignData(sig_req_id,userDomain);
String nowDate = getdate(0);
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="No-Cache">
</head>
<script type="text/javascript">
function init(){
<% if( fnDateDiff(result[4],nowDate) >= 0 ){ %>
parent.fnHndSingSocket('', '', '9999', '', '', '');
<% } else { %>
parent.fnHndSingSocket('<%=result[0]%>', '<%=result[1]%>', '<%=result[2]%>', '<%=result[3]%>', '<%=result[4]%>', '<%=result[5]%>');
<% } %>
}
init();
</script>
</html>
Ran into some issues on some of our Java sites today and needed a quick fix to protect the sites from malicious Cross Site Scripting (XSS) attempts. If you're not aware of what XSS is and have websites that have sensitive user data, you may want to read up, you're probably vulnerable, which means your users are vulnerable. I'm not claiming this is a perfect solution, but it was easy to implement and corrected the vulnerabilities with form and url injection. We basically have a Servlet Filter that's going to intercept every request sent to the web application and then we use an HttpServletRequestWrapper to wrap and override the getParameter methods and clean any potential script injection.
Here's the Filter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.greatwebguy.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class CrossScriptingFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { this .filterConfig = filterConfig; } public void destroy() { this .filterConfig = null ; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter( new RequestWrapper((HttpServletRequest) request), response); } } |
Here's the wrapper:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package com.greatwebguy.filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public final class RequestWrapper extends HttpServletRequestWrapper { public RequestWrapper(HttpServletRequest servletRequest) { super (servletRequest); } public String[] getParameterValues(String parameter) { String[] values = super .getParameterValues(parameter); if (values== null ) { return null ; } int count = values.length; String[] encodedValues = new String[count]; for ( int i = 0 ; i < count; i++) { encodedValues[i] = cleanXSS(values[i]); } return encodedValues; } public String getParameter(String parameter) { String value = super .getParameter(parameter); if (value == null ) { return null ; } return cleanXSS(value); } public String getHeader(String name) { String value = super .getHeader(name); if (value == null ) return null ; return cleanXSS(value); } private String cleanXSS(String value) { //You'll need to remove the spaces from the html entities below value = value.replaceAll( "<" , "& lt;" ).replaceAll( ">" , "& gt;" ); value = value.replaceAll( "\\(" , "& #40;" ).replaceAll( "\\)" , "& #41;" ); value = value.replaceAll( "'" , "& #39;" ); value = value.replaceAll( "eval\\((.*)\\)" , "" ); value = value.replaceAll( "[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']" , "\"\"" ); value = value.replaceAll( "script" , "" ); return value; } } |
Add this to the top of your web.xml:
1 2 3 4 5 6 7 8 9 10 | < filter > < filter-name >XSS</ filter-name > < display-name >XSS</ display-name > < description ></ description > < filter-class >com.greatwebguy.filter.CrossScriptingFilter</ filter-class > </ filter > < filter-mapping > < filter-name >XSS</ filter-name > < url-pattern >/*</ url-pattern > </ filter-mapping > |
I'm sure the cleanXSS replacements aren't the most efficient way of doing this, you could replace it StringEscapeUtils.escapeHtml from commons lang to simplify it a little, it's up to you, it all depends on what your site is doing and whether it's going to be a pain having all the html escaped, you could also adjust the url-pattern of the filter to be more specific to your application urls, so that everything under your app isn't running through the filter.
Some things to be aware of with this approach, you'll need to account for what you've encoded or in some cases you'll end up with weird characters in your database and possibly in validation of your input boxes. Some would recommend a more positive validation rather than negative validation and only allow a certain range of characters, it's up to you, but it is something to think about.
value = value.replaceAll(“(?i)script”, “”); instead of
value = value.replaceAll(“(?i)script”, “”); for a case insensitive replacement.
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 27 |
28 |