泽西岛 Web 服务在从 GET 请求返回 pojo 时挂起



我在Oracle WebLogic 11g上使用Jersey 1.9建立了一个jax-rs Web服务。我的 Web 服务有两种 Web 方法:

    @Path("{lid}/name")
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getName(@PathParam("ebid") long ebid, @PathParam("lid") long lid)
    {
        System.out.println("LocationService.getName");
        LocationLocalSession ejb = EJBLookup.getLocationLocalSession();
        LocationVO location = ejb.getLocationInfo(ebid, lid);
        System.out.println("return location name: " + location.getLocationName());
        return location.getLocationName();
    }

第一个(上面)完全按预期工作,没有问题。 它通过 EJB 检索位置对象,并以纯文本形式返回该位置对象的名称。我设置此方法只是为了测试Web服务是否正常工作。我真的只关心第二种方法。

下面是第二种网络方法。它的功能与第一个几乎相同。它通过 EJB 检索位置对象,但以 JSON 形式返回整个位置对象,而不仅仅是名称。当我调用此方法(ajax 或直接 Web 浏览器)时,该方法将执行,它检索位置对象,按预期将 print 语句打印到应用服务器日志中,但从不返回响应,它只是无限期挂起。

@Path("{lid}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public LocationVO get(@PathParam("ebid") long ebid, @PathParam("lid") long lid)
{
    System.out.println("LocationService.get");
    LocationLocalSession ejb = EJBLookup.getLocationLocalSession();
    LocationVO location = ejb.getLocationInfo(ebid, lid);
    System.out.println("return location: " + location.getLocationName());
    return location;
}
最终,

由于没有响应,请求超时,我最终在 WebLogic 中遇到了一个卡住的线程。有没有人知道为什么此方法不会返回响应?我可以根据需要创建任意数量的方法来返回字符串/纯文本,并且它们始终有效,但是一旦我尝试将对象返回为 JSON,它每次都会挂起。这是我在网络中的泽西岛配置.xml以防它可以提供任何线索:

<servlet>
    <display-name>JAX-RS Servlet</display-name>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>gis.ws.ServiceApplication</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

谢谢

编辑:添加位置VO

public class LocationVO implements Serializable
{
    private static final long serialVersionUID = 1L;
    //The Database Fields variable should be used in SQL queries
    public static final String LOCATION_DATABASE_FIELDS = 
            "LOCATION.LOCATION_ID LOCATION__LOCATION_ID, "+
            "LOCATION.EVENT_BOARD_ID LOCATION__EVENT_BOARD_ID, " +                              
            "LOCATION.LOCATION_NAME LOCATION__LOCATION_NAME, " +
            "LOCATION.ADDRESS LOCATION__ADDRESS, "+
            "LOCATION.CITY LOCATION__CITY, "+
            "LOCATION.STATE LOCATION__STATE, "+
            "LOCATION.ZIPCODE LOCATION__ZIPCODE, "+
            "LOCATION.COUNTRY LOCATION__COUNTRY, "+
            "LOCATION.PHONE LOCATION__PHONE, "+
            "LOCATION.MAP_GRID LOCATION__MAP_GRID, "+
            "LOCATION.COMMENTS LOCATION__COMMENTS, "+
            "LOCATION.CREATED_BY LOCATION__CREATED_BY, "+
            "LOCATION.CREATED_DATE LOCATION__CREATED_DATE ";
    private long    locationId   = 0l;
    private long    eventBoardId = 0l;
    private String  locationName = null;
    private String  address      = null;
    private String  city         = null;
    private String  state        = null;
    private String  zipcode      = null;
    private String  country      = null;
    private String  phone        = null;
    private String  mapGrid      = null;
    private String  comments     = null;
    private long    createdBy    = 0l;
    private Date    createdDate  = null;
    private String  displayName  = null;
    //this field is not part of the database:
    private long    requestor    = 0l;
    public LocationVO()
    {}
    public  long   getLocationId()                      {return this.locationId;}
    public  void   setLocationId(long locationId)       {this.locationId = locationId;}
    public  long   getEventBoardId()                    {return this.eventBoardId;}
    public  void   setEventBoardId(long eventBoardId)   {this.eventBoardId = eventBoardId;}
    public  String getLocationName()                    {return this.locationName;}
    public  void   setLocationName(String locationName) {this.locationName = StringUtilities.safeTrim(locationName);}
    public  String getAddress()                         {return this.address;}
    public  void   setAddress(String address)           {this.address = StringUtilities.safeTrim(address);}
    public  String getCity()                            {return this.city; }
    public  void   setCity (String city)                {this.city  = StringUtilities.safeTrim(city);}
    public  String getState()                           {return this.state; }
    public  void   setState(String state)               {this.state = StringUtilities.safeTrim(state);}
    public  String getZipcode ()                        {return this.zipcode; }
    public  void   setZipcode (String zipcode)          {this.zipcode = StringUtilities.safeTrim(zipcode);}
    public  String getCountry ()                        {return this.country; }
    public  void   setCountry (String country)          {this.country = StringUtilities.safeTrim(country);}
    public  String getPhone()                           {return this.phone;}
    public  void   setPhone(String phone)               {this.phone = StringUtilities.safeTrim(phone);}
    public  String getMapGrid()                         {return this.mapGrid;}
    public  void   setMapGrid(String mapGrid)           {this.mapGrid = StringUtilities.safeTrim(mapGrid);}
    public  String getComments()                        {return this.comments;}
    public  void   setComments(String comments)         {this.comments = StringUtilities.safeTrim(comments);}
    public  long   getCreatedBy()                       {return this.createdBy;}
    public  void   setCreatedBy(long createdBy)         {this.createdBy = createdBy;}
    public  Date   getCreatedDate()                     {return this.createdDate;}
    public  void   setCreatedDate(Date createdDate)     {this.createdDate = createdDate;}
    public  long   getRequestor()                       {return this.requestor;}
    public  void   setRequestor(long requestor)         {this.requestor = requestor;}
    public  String getDisplayName()                     {return this.displayName;}
    public  void   setDisplayName(String displayName)   {this.displayName = StringUtilities.safeTrim(displayName);}
    public  boolean getValid() 
    {
        return (this.locationName != null && this.locationName.length() > 0)
         || (this.address != null && this.address.length() > 0)
         || (this.city != null  && this.city.length() > 0);
    }
    public LocationVO copy()
    {
        LocationVO copy = new LocationVO();
        copy.locationId   = this.locationId;
        copy.eventBoardId = this.eventBoardId;
        copy.locationName = this.locationName;
        copy.address      = this.address;
        copy.city         = this.city;
        copy.state        = this.state;
        copy.zipcode      = this.zipcode;
        copy.country      = this.country;
        copy.phone        = this.phone;
        copy.mapGrid      = this.mapGrid;
        copy.comments     = this.comments;
        copy.createdBy    = this.createdBy;
        copy.createdDate  = this.createdDate;
        copy.displayName  = this.displayName;
        return copy;
    }
    public String getLocationForDisplayAsHtml()
    {
        StringBuffer addressBlock = new StringBuffer();
        if (locationName != null)
        { 
            addressBlock.append(locationName);
            if (address != null || city != null || state != null  || zipcode != null  || country != null || phone != null || mapGrid != null)
                addressBlock.append("<br/>");
            else return addressBlock.toString();
        }

        if (address != null)
        { 
            addressBlock.append(address);
            if (city != null || state != null  || zipcode != null  || country != null || phone != null || mapGrid != null)
                addressBlock.append("<br/>");
            else return addressBlock.toString();
        }
        if (city != null)
        {
            addressBlock.append(city);
            if (state != null)
            {
                addressBlock.append(",&nbsp;"+state);
            }
            addressBlock.append("&nbsp;");
        }
        else if (state != null)
        {
            addressBlock.append(state +"&nbsp;");
        }   
        if (zipcode != null) addressBlock.append(zipcode);
        if ((city != null || state != null  || zipcode != null)  && country != null || phone != null || mapGrid != null)
            addressBlock.append("<br/>");
        if (country != null) addressBlock.append(country +"&nbsp;");
        if (phone != null) addressBlock.append(phone +"&nbsp;");
        if (mapGrid != null) addressBlock.append(mapGrid);
        return addressBlock.toString();
    }
    public String getLocationForDisplayAsHtml(String highlight)
    {
      return this.getLocationForDisplayAsHtml().replaceAll(highlight,"<span style='background-color: #FFFF00'>"+highlight+"</span>");
    }

    /**
     * This method returns a String representation of this object for audit trail purposes.
     */
    public String asString()
    {
        StringBuffer result = new StringBuffer();
        boolean first = true;
        if(this.locationName != null)
        {
            if (!first) result.append(", ");
            result.append(this.locationName);
            first = false;
        }
        if(this.address != null)
        {
            if (!first) result.append(", ");
            result.append(this.address);
            first = false;
        }
        if(this.city != null)
        {
            if (!first) result.append(", ");
            result.append(this.city);
            first = false;
        }
        if(this.state != null)
        {
            if (!first) result.append(", ");
            result.append(this.state);
            first = false;
        }
        if(this.zipcode != null)
        {
            if (!first) result.append(", ");
            result.append(this.zipcode);
            first = false;
        }
        if(this.country != null)
        {
            if (!first) result.append(", ");
            result.append(this.country);
            first = false;
        }
        if(this.mapGrid != null)
        {
            if (!first) result.append(", ");
            result.append(this.mapGrid);
            first = false;
        }
        return result.toString();
    }

    /**
     * This method returns a String representation of this object for audit trail purposes.
     */
    public String toString()
    {
        StringBuffer result = new StringBuffer(this.locationId +",");
        if(this.eventBoardId != 0l)   result.append(this.eventBoardId +",");
        if(this.locationName != null) result.append(this.locationName +",");
        if(this.address != null)      result.append(this.address +",");
        if(this.city != null)         result.append(this.city +",");
        if(this.state != null)        result.append(this.state +",");
        if(this.zipcode != null)      result.append(this.zipcode +",");
        if(this.country != null)      result.append(this.country +",");
        if(this.mapGrid != null)      result.append(this.mapGrid +",");
        if(this.comments != null)     result.append(this.comments +",");
        if(this.createdBy != 0l)      result.append(this.createdBy +",");
        if(this.createdDate != null)  result.append(this.createdDate +",");
        if(this.displayName != null)  result.append(this.displayName +",");
        if(result.length() > Constants.AUDIT_TRAIL_DATA_STORAGE_FIELD_LENGTH)
            return result.toString().substring(0, Constants.AUDIT_TRAIL_DATA_STORAGE_FIELD_LENGTH);
        else
            return result.toString();
    }
}

尝试使用两个基本的 REST 资源来测试您的配置。如果两者都失败了,那就是Oracle WebLogic中的东西。

@Path("test1")
@GET
@Produces(MediaType.APPLICATION_JSON)
public LocationVO test1()
{
    LocationVO location = new LocationVO();
    location.setLocationName("somewhere");
    return location;
}
@Path("test2")
@GET
@Produces(MediaType.APPLICATION_JSON)
public JSONObject test2()
{
    return new JSONObject().put("test2", "works");  
}

https://jersey.java.net/documentation/1.19/json.html

为了能够正确映射 POJO,解析器必须知道如何处理对象。向对象添加@XmlRootElement可以让分析器知道从哪里开始。

@XmlRootElement
public class LocationVO implements Serializable {
    ...
}

附言另一个提示是使用记录器,而不是System.out.println(),因为当应用程序部署到服务器时,它也会打印logg。"sysout"只会打印到您的主机。

最新更新