2012-10-14 3 views
14

나는 지금 저지를 시험하고 있으며, netbeans에서 웹 서비스를 설정하려면 this 링크를 따라 갔다. 엔티티 클래스와 내 REST 클래스가 있습니다. javafx2 클라이언트에서 객체 (이 경우 Users 객체)를 추가, 편집, 삭제, 요청할 수 있습니다.저지 생산 미디어 유형 충돌

그러나 지금은 간단한 인증을 위해 웹 서비스에 새 메서드를 추가하려고합니다. 우선은 Users.java 파일의 새 명명 된 쿼리 (Users.login) 추가 : 이후

@NamedQueries({ 
    @NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"), 
    @NamedQuery(name = "Users.login", query = "SELECT u FROM Users u WHERE u.username = :username AND u.password = :password"), 
    @NamedQuery(name = "Users.findById", query = "SELECT u FROM Users u WHERE u.id = :id"), 
    @NamedQuery(name = "Users.findByUserlevel", query = "SELECT u FROM Users u WHERE u.userlevel = :userlevel"), 
    @NamedQuery(name = "Users.findByDisabled", query = "SELECT u FROM Users u WHERE u.disabled = :disabled") 
}) 

을 내 UsersFacadeREST.java 파일에 코드를 다음 추가 된 (넷빈즈 7.2에 의해 생성) :

@GET 
@Path("{username}/{password}") 
@Produces({"application/xml", "application/json"}) 
public Users login(@PathParam("username") String username, @PathParam("password") String password) { 
    return em.createNamedQuery("login", Users.class) 
      .setParameter("username", username) 
      .setParameter("password", password) 
      .getSingleResult(); 
} 
웹 서비스 배포하려고 할 때

그러나, 나는 오류를 다음 수신 :이에 새로 온 사람으로

SEVERE: Producing media type conflict. The resource methods public entities.Users service.UsersFacadeREST.login(java.lang.String,java.lang.String) and public java.util.List service.UsersFacadeREST.findRange(java.lang.Integer,java.lang.Integer) can produce the same media type 

를, 내가 로그인() 메소드는 findRange와의 충돌을주는 이유 단서가 없다()? 첫 번째는 String 매개 변수가 2 개이며 Users 객체를 제공하고 두 번째 매개 변수는 두 개의 정수 매개 변수를 가지며 List 객체를 반환합니다. 슈퍼 클래스의

@GET 
@Path("{from}/{to}") 
@Produces({"application/xml", "application/json"}) 
public List<Users> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) { 
    return super.findRange(new int[]{from, to}); 
} 

코드 (AbstractFacade.java)

: 나는 거 내 웹 서비스에 추가 된 일부 사용자 지정 쿼리가 필요 해요로이 문제를 해결 할 수있는 방법 ... 완료

이 있습니까

public List<T> findRange(int[] range) { 
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
    cq.select(cq.from(entityClass)); 
    javax.persistence.Query q = getEntityManager().createQuery(cq); 
    q.setMaxResults(range[1] - range[0]); 
    q.setFirstResult(range[0]); 
    return q.getResultList(); 
} 

답변

24

두 가지 방법 모두 동일한 URI와 일치하는 경로 템플릿을 사용하고 있습니다. "{a}/{b}""{c}/{d}"과 동일합니다. 동일한 방식으로 "{username}/{password}""{from}/{to}"과 같습니다. 두 가지 방법 모두 동일한 미디어 유형을 사용하기 때문에 모호성이 있습니다. 경로 템플릿의 정규 표현식을 사용하여보다 구체적으로 수정할 수 있습니다. 나는. "{from}/{to}"은 항상 숫자 여야하므로 다음과 같이 변경하여 명확하게 할 수 있습니다. "{from: [0-9]+}/{to: [0-9]+}".

어쨌든 사용자 이름과 비밀번호에서 일반 사용자를 선택하지 않으셨습니까? 귀하의 경우에 두 개의 자원 각각에 다른 URI "하위 공간"을 사용하는 것이 훨씬 더 나은 것처럼 보입니다. 예 : login/{username}/{password}ranges/{from}/{to}

는하지만, 디자인에 대한 몇 가지 포인트 :

  1. IT는 URI에 암호를 넣어 아주 나쁜 생각이다. 절대로 해보지 마십시오! 기존의 검증 된 인증 체계를 살펴보십시오. 다시 시도하지 마십시오.
  2. 검색어 매개 변수를 사용하여 범위를 지정하는 것을 고려해보십시오. ("myapp.com/calendar/events"와 같은) 일부 수집 리소스가있는 경우 쿼리 매개 변수를 사용하여 범위를 모델링 할 수 있습니다. "myapp.com/calendar/events?from=xxx & to = yyy
+0

답변 주셔서 감사합니다! 첫 번째 요점에 대해, 나는 자바 클라이언트에서 jax- rs webservice하지만 아직 하나도 찾을 수 없었습니다. 알고 계십니까? 두 번째 사항에 대해서, 예를 들어 사용자 컬렉션을 원하지만 다른 컬렉션을 제공하는 다른 이름의 쿼리가 있습니다 (국가별로 필터링 된 사용자, 액세스 수준 등 ...) 쿼리 매개 변수를 사용하여 메서드가 어떤 쿼리를 실행해야하는지 알 수 있도록하는 좋은 해결책입니까? 예 : myapp.com/calendar/events?qry = byCountry 또는 qry = byAccessLevel – Perneel

+1

1) 가장 간단한 방법은 HTTP BASIC 인증을 사용하는 것입니다. SSL (HTTPS)를 사용하여 - 인터넷 검색을 시도해보십시오. 2) 네, 쿼리 매개 변수에 필터를 지정하는 것이 좋습니다 –

+0

최고, 시간 주셔서 감사합니다. – Perneel